Форум сайта python.su
У меня есть форма (ModelForm), которая используется несколько раз, потому описана в отдельном файле, например такая
class TestForm(forms.ModelForm):
manager = forms.ModelChoiceField(queryset=Manager.objects.filter(city=...))
...
class Meta:
...
Отредактировано (Окт. 20, 2008 00:45:59)
Офлайн
Объясни на задаче/примере работы, а то я ничего не понял. Цель какая?
Офлайн
Есть форма добавления продукта на склад. В форме продукта есть поле менеджер, а менеджеры бывают разных городов. В момент заполнения формы город, по которому нужно отфильтровать список менеджеров известен и надо его передать в filter() queryset'а менеджера.
Сама форма описана в отдельном файле, т.е., скажем, через request нельзя передать в форму город для фильтра.
Офлайн
AJAX автодополнение с ‘related_fields’ как раз то что Вам нужно. Работает отлично, и легко использовать.
Офлайн
Ммммм… Спасибо. Использую, но в других формах :) Но не совсем то.
Я неправильно сказал. Не в момент заполнения, а в момент создания формы, т.е. form = TestForm() уже известен город. Было бы классно так: form = TestForm(city=City.objects.get(…)), потом этот city попадает в __init__ (тот, который будет от TestForm), который модифицирует queryset, или добавляет поле динамически. Вот здесь то и затык, не знаю, как такое сделать. Наверное, так не бывает :)
Отредактировано (Окт. 21, 2008 01:08:24)
Офлайн
Хе. Field.initial не поможет случайно :)?
Офлайн
FerromanТак так и сделайте.
Было бы классно так: form = TestForm(city=City.objects.get(…)), потом этот city попадает в __init__ (тот, который будет от TestForm), который модифицирует queryset, или добавляет поле динамически.
FerromanНет.
Хе. Field.initial не поможет случайно smile?
Офлайн
А такий варіант не пробували :
class TestForm(forms.ModelForm):
def __init__(self, city=None, *args, **kwargs):
self.city = city
super(self, TestForm).__init__(*args, **kwargs)
if self.city:
self.fields['manager'] = forms.ModelChoiceField(queryset = Manager.objects.filter(city=self.city))
else:
self.fields['manager'] = forms.ModelChoiceField(queryset = Manager.objects.all())
...
testform = TestForm(City.objects.get(pk = some_city_id))
Отредактировано (Окт. 21, 2008 12:39:58)
Офлайн
Да, громандное спасибо, smal, Daevaorn. Теперь получилось. Не догадался использовать словарь self.fields, создавал поля непосредственно, отчего они уже не работали.
Но, пришлось несколько изменить код, т.к. ModelForm принимает еще разное, как то request.POST при отправке формы.
Таким образом (в меру своего понимания процесса, может и наворотил лишнего):
class TestForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
# city придет в kwargs при первой инициализации и надо будет его вытащить,
# в противном случае ModelForm'овский __init__ ругнется на неизвестный аргумент
if 'city' in kwargs:
self.city = kwargs.pop('city')
else:
# один раз инициализированному полю уже не понадобится city, так что все будет хорошо и после request.POST
# даже в таком случае
self.city = None
super(TestForm, self).__init__(*args, **kwargs)
if self.city:
self.fields['manager'] = forms.ModelChoiceField(queryset = Manager.objects.filter(city=self.city))
else:
self.fields['manager'] = forms.ModelChoiceField(queryset = Manager.objects.all())
# views.py
def smth(request):
form = None
if "POST" == request.method:
# это случай с отправленной формой, здесь уже не нужен city, поле уже инициализировано с нужным фильтром
form = TestForm(request.POST)
# а если формы нет, создаем и передаем ей нужный City
if form is None:
form = TestForm(city=City.objects.get(pk = some_city_id))
return render_to_response...
Отредактировано (Окт. 21, 2008 14:02:21)
Офлайн
Ясно, я так и не понял вопрос.
Офлайн