Django ModelChoiceField: набор фильтрующих запросов и установка значения по умолчанию в качестве объекта
У меня есть класс Django Form, которому это нравится в Models
:
class AccountDetailsForm(forms.Form):
...
adminuser = forms.ModelChoiceField(queryset=User.objects.all())
Это работает нормально, но у него есть некоторые ограничения, с которыми я не могу работать:
(1) Я хотел бы использовать фильтр в наборе запросов на основе переменной accountid
, переданной в форму, например:
User.objects.filter(account=accountid)
Это не может работать в модели, потому что accountid
не может быть передано как переменная, конечно.
Из этого следует, что queryset
должно быть каким-то образом определено в Views
, но насколько я могу видеть это обязательное поле в классе Form.
(2) Я хотел бы сделать выбор по умолчанию AccountDetailsForm
объекта в базе данных, который я могу выбрать в Views
следующим образом:
User.objects.filter(account=accountid).filter(primary_user=1)
Я попытался указать adminuser как значение по умолчанию в форме (которое работает с другими стандартными полями формы, например CharField
):
adminuser = User.objects.filter(account=accountid).filter(primary_user=1)
...
form = AccountDetailsForm({'adminuser': adminuser})
return render_to_response('accounts/edit/accountdetails.html',
{'form': form, 'account':account})
Но не повезло.
Должен ли я использовать что-то другое, кроме ModelChoiceField
, учитывая гибкость, которая мне нужна здесь?
Спасибо.
Ответы
Ответ 1
Переопределите метод init и примите новый аргумент ключевого слова
class AccountDetailsForm(forms.Form):
...
adminuser = forms.ModelChoiceField(queryset=User.objects.all())
def __init__(self, *args, **kwargs):
accountid = kwargs.pop('accountid', None)
super(AccountDetailsForm, self).__init__(*args, **kwargs)
if accountid:
self.fields['adminuser'].queryset = User.objects.filter(account=accountid)
form = AccountDetailsForm(accountid=3)
Вы всегда можете просто установить параметры вручную в представлении.
form = AccountDetailsForm()
form.fields['adminuser'].queryset = User.objects.filter(account=accountid)
Будьте предупреждены: вы не устанавливаете значения по умолчанию, передавая в словаре форму, как в вашем примере.
На самом деле вы создаете Bound Form, потенциально запуская валидацию и весь этот джаз.
Чтобы установить значения по умолчанию, используйте аргумент initials.
form = AccountDetailsForm(initial={'adminuser':'3'})
Ответ 2
Вы можете переопределить поле в представлении
yourForm = AccountDetailsForm()
yourForm.fields['accomodation'] = forms.ModelChoiceField(User.objects.filter(account=accountid).filter(primary_user=1))