具有ModelMultipleChoiceField的Django表单呈现为空

时间:2018-09-26 15:56:42

标签: python django

我在使用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)

1 个答案:

答案 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.pkuser.username