如何在Django中的ModelForm中使用该请求

时间:2012-01-12 20:02:54

标签: django forms

我想创建一个查询集,其中当前用户用作ModelForm中的过滤器:

class BookSubmitForm(ModelForm):
    book = forms.ModelChoiceField(queryset=Book.objects.filter(owner=request.user),)
...

Django是否将请求传递给表单?这是好习惯吗?我该如何使用该请求? (当然没有定义名称请求)

编辑:

我尝试了另一个解决方案,即在视图中调用表单并传递请求:

form = BookSubmitForm(request)

然后以我使用的形式:

class BookSubmitForm(ModelForm):
    def __init__(self, request, *args, **kwargs):
        super(BookSubmitForm, self).__init__(*args, **kwargs)
        self.fields["library"].queryset = Library.objects.filter(owner=request.user)

它有效并且代码在表单中。现在我不确定它是最好的解决方案,可以改进吗?

2 个答案:

答案 0 :(得分:32)

不,请求未传递给ModelForm。您需要在视图中执行以下操作:

form = BookSubmitForm()
form.fields['book'].queryset = Book.objects.filter(owner=request.user)
# pass form to template, etc

正如您所说,将它封装在Form对象中通常更加清晰,特别是如果您有多个需要过滤查询集的字段。要执行此操作,请覆盖表单的__init__()并让其接受request的kwarg:

class BookSubmitForm(ModelForm):
    def __init__(self, *args, **kwargs):
        self.request = kwargs.pop("request")
        super(BookSubmitForm, self).__init__(*args, **kwargs)
        self.fields["book"].queryset = Book.objects.filter(owner=self.request.user)
        self.fields["whatever"].queryset = WhateverModel.objects.filter(user=self.request.user)

然后只需在视图中实例化BookSubmitForm时传递请求:

def book_submit(request):
    if request.method == "POST":
        form = BookSubmitForm(request.POST, request=request)
        # do whatever
    else:
        form = BookSubmitForm(request=request)
    # render form, etc

答案 1 :(得分:2)

AdamKG answer扩展到基于类的视图 - 覆盖get_form_kwargs方法:

class PassRequestToFormViewMixin:
    def get_form_kwargs(self):
        kwargs = super(PassRequestToFormViewMixin, self).get_form_kwargs()
        kwargs['request'] = self.request
        return kwargs

from django.views.generic.edit import CreateView
class BookSubmitCreateView(PassRequestToFormViewMixin, CreateView):
    form_class = BookSubmitForm
# same for EditView

然后以表格形式:

from django.forms import ModelForm
class BookSubmitForm(ModelForm):
    def __init__(self, *args, **kwargs):
        self.request = kwargs.pop("request")
        super(BookSubmitForm, self).__init__(*args, **kwargs)
        ...