我在使用ModelMultipleChoiceField
设置表单时遇到麻烦,其中查询集取决于用户。我的目标是实现导出功能。
我的视图如下:
class ExportView(FormView):
template_name = 'ExportTemplate.html'
def get(self, request, *args, **kwargs):
self.form_class = ExportForm(user = request.user)
return render(request, self.template_name, {'form': self.form_class})
def get_success_url(self):
return '/addrbook/'
def form_valid(self, form):
# This method is called when valid form data has been POSTed.
# It should return an HttpResponse.
return super().form_valid(form)
表格:
class ExportForm(forms.Form):
def __init__(self, user, *args, **kwargs):
usersContacts = ContactManager().getAllUsersContacts()
self.contactList = forms.ModelMultipleChoiceField(queryset = usersContacts[str(user)])
print(usersContacts[str(user)])
super(ExportForm, self).__init__(*args, **kwargs)
我确认queryset不为空,它包含模型对象列表。
我的模板如下:
<form method="post">{% csrf_token %}
{{ form }}
<input type="submit">
</form>
唯一呈现的是提交按钮。
让我完全不确定python基础的另一件事是该代码:
class ExportForm(forms.Form):
contactList = forms.ModelMultipleChoiceField(queryset = [])
def __init__(self, user, *args, **kwargs):
usersContacts = ContactManager().getAllUsersContacts()
self.contactList.queryset = usersContacts[str(user)]
print(usersContacts[str(user)])
super(ExportForm, self).__init__(*args, **kwargs)
返回了运行时错误:
'ExportForm' object has no attribute 'contactList'
怎么可能? contactList成员是ExportForm类定义的一部分,“自身”应指向该类的对象。
有人可以向我解释为什么表单字段为空和/或为我提供了一种将用户传递到表单的更好方法吗?
编辑:这是我为使答案起作用而做出的更改,尽管我现在偶然发现了另一个问题(该字段需要一个查询集,而不是模型对象列表):
查看:
class ExportView(FormView):
template_name = 'ExportTemplate.html'
form_class = ExportForm
def get_form_kwargs(self):
kwargs = super(ExportView, self).get_form_kwargs()
kwargs['user'] = self.request.user
return kwargs
表格:
class ExportForm(forms.Form):
contactList = forms.ModelMultipleChoiceField(queryset = Contact.objects.none())
def __init__(self, *args, **kwargs):
user = kwargs['user']
kwargs.pop('user', None)
super(ExportForm, self).__init__(*args, **kwargs)
usersContacts = ContactManager().getAllUsersContacts()
self.fields['contactList'].queryset = usersContacts[str(user)]
print(self.fields['contactList'].queryset)
答案 0 :(得分:2)
首先,您应在每次实例化表单时都将user
传递给表单,而不仅限于get
方法中。使用FormView
进行此操作的方法是覆盖get_form_kwargs
。
def get_form_kwargs(self):
kwargs = super(ExportForm, self).get_form_kwargs()
kwargs[user] = self.request.user
return kwargs
然后您可以删除get()
方法。
然后,在表单类中,应使用none()
方法而不是空列表来获取空查询集。在__init__
方法中,您可以从kwargs
弹出用户,然后在编辑字段之前调用super()
。您通过contactList
而不是self.fields
编辑self.contactList
字段。请注意,在Django中,字段名称的推荐样式为contact_list
,而不是contactList
。
class ExportForm(forms.Form):
contactList = forms.ModelMultipleChoiceField(queryset=YourModel.objects.none())
def __init__(self, *args, **kwargs):
user = kwargs.pop('user')
super(ExportForm, self).__init__(*args, **kwargs)
usersContacts = ContactManager().getAllUsersContacts()
self.fields['contactList'].queryset = usersContacts[str(user)]
您没有显示ContactManager()
代码,但是使用str(user)
作为字典键看起来很脆弱。最好使用user.pk
或user.username
。