Django ModelChoiceField:筛选查询集并将默认值设置为对象
我在Django ModelChoiceField:筛选查询集并将默认值设置为对象,django,django-forms,Django,Django Forms,我在模型中定义了一个Django表单类,如下所示: class AccountDetailsForm(forms.Form): ... adminuser = forms.ModelChoiceField(queryset=User.objects.all()) 这很好,但它有一些我无法克服的局限性: (1) 我希望根据传递给表单的变量accountid在queryset上使用一个过滤器,如下所示: User.objects.filter(account=accountid)
模型中定义了一个Django表单类,如下所示:
class AccountDetailsForm(forms.Form):
...
adminuser = forms.ModelChoiceField(queryset=User.objects.all())
这很好,但它有一些我无法克服的局限性:
(1) 我希望根据传递给表单的变量accountid
在queryset上使用一个过滤器,如下所示:
User.objects.filter(account=accountid)
User.objects.filter(account=accountid).filter(primary_user=1)
class AccountDetailsForm(forms.Form):
adminuser = forms.ModelChoiceField(queryset=User.objects.all())
account_id = forms.IntegerField() # or ModelChoiceField if that applies
def clean(self):
account_id = self.cleaned_data['account_id']
self.cleaned_data['adminuser'] = User.objects.filter(account_id=account_id)
return self.cleaned_data
这在模型中不起作用,因为accountid
当然不能作为变量传递
因此,queryset
必须以某种方式在视图中定义,但据我所知,它是表单类中的必填字段
(2) 我希望默认选择数据库中的对象AccountDetailsForm
,我可以在视图中选择该对象,如下所示:
User.objects.filter(account=accountid)
User.objects.filter(account=accountid).filter(primary_user=1)
class AccountDetailsForm(forms.Form):
adminuser = forms.ModelChoiceField(queryset=User.objects.all())
account_id = forms.IntegerField() # or ModelChoiceField if that applies
def clean(self):
account_id = self.cleaned_data['account_id']
self.cleaned_data['adminuser'] = User.objects.filter(account_id=account_id)
return self.cleaned_data
我已经尝试将adminuser指定为表单中的默认值(这适用于其他标准表单字段,如CharField
):
但是没有运气
考虑到此处所需的灵活性,我是否应该使用除modelcoocefield
以外的其他功能
谢谢。重写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)
请注意:将字典传递给示例中的表单并不是在设置默认值
实际上,您正在创建一个绑定表单,可能会触发验证和所有这些
要设置默认值
可以替代视图中的字段
yourForm = AccountDetailsForm()
yourForm.fields['accomodation'] = forms.ModelChoiceField(User.objects.filter(account=accountid).filter(primary_user=1))
在Django 2.0中,您可以将对象(User
在您的情况下)从视图
传递到表单
,如下所示(您必须首先从DB检索obj):
它会给你一个默认选择的对象(回答你的2个问题)这里还没有提到的是方法。此方法专门用于自定义验证
例如,您可以这样做:
User.objects.filter(account=accountid)
User.objects.filter(account=accountid).filter(primary_user=1)
class AccountDetailsForm(forms.Form):
adminuser = forms.ModelChoiceField(queryset=User.objects.all())
account_id = forms.IntegerField() # or ModelChoiceField if that applies
def clean(self):
account_id = self.cleaned_data['account_id']
self.cleaned_data['adminuser'] = User.objects.filter(account_id=account_id)
return self.cleaned_data
clean()方法在默认的clean方法之后被调用,因此您可以使用self.cleaned_数据(与视图中的form.cleaned_数据相同)并按自己的意愿返回它
更好的是,您可以根据要清理的字段(def clean\u adminuser
)命名方法,使其更易于阅读
def clean_adminuser(self):
account_id = self.cleaned_data['account_id']
return User.objects.filter(account_id=account_id)
此外,如果有任何问题需要处理,您也可以使用此方法进行呼叫。您好,谢谢您的回复。在视图中设置查询集效果很好。我无法解决的部分是将ModelChoiceField的绑定表单值(而不是默认值)设置为User.objects.filter(account=accountid.filter)(primary_User=1)。谢谢。@jon在表单中?我目前的解决方案就是这里的,但我觉得这不是最有效的方法: