Django ModelChoiceField:过滤查询集并将默认值设置为对象

eli*_*eli 57 django django-forms

我有一个Django Form类定义喜欢这个Models:

class AccountDetailsForm(forms.Form):
    ...
    adminuser = forms.ModelChoiceField(queryset=User.objects.all())
Run Code Online (Sandbox Code Playgroud)

这工作正常,但它有一些限制我似乎无法解决:

(1)我想在查询集上使用过滤器,基于accountid传递给表单的变量,如下所示:

User.objects.filter(account=accountid)
Run Code Online (Sandbox Code Playgroud)

这当然不能在模型中起作用,因为accountid当然不能作为变量传递.

因此queryset必须在某种程度上定义Views,但据我所知,它是Form类中的必填字段.

(2)我想AccountDetailsForm在数据库中默认选择一个对象,我可以这样选择Views:

User.objects.filter(account=accountid).filter(primary_user=1)
Run Code Online (Sandbox Code Playgroud)

我已经尝试将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})
Run Code Online (Sandbox Code Playgroud)

但没有运气.

我应该使用除了ModelChoiceField我需要的灵活性以外的其他东西吗?

谢谢.

Yuj*_*ita 104

覆盖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)
Run Code Online (Sandbox Code Playgroud)

您也可以随时在视图中手动设置选项.

form = AccountDetailsForm()
form.fields['adminuser'].queryset = User.objects.filter(account=accountid)
Run Code Online (Sandbox Code Playgroud)

请注意:您没有通过将字典传递到示例中的表单来设置默认值.

您实际上正在创建一个绑定表单,可能会触发验证和所有爵士乐.

要设置默认值,请使用initials参数.

form = AccountDetailsForm(initial={'adminuser':'3'})
Run Code Online (Sandbox Code Playgroud)


小智 6

您可以覆盖视图中的字段

yourForm = AccountDetailsForm()

yourForm.fields['accomodation'] = forms.ModelChoiceField(User.objects.filter(account=accountid).filter(primary_user=1))
Run Code Online (Sandbox Code Playgroud)