How to use the request in a ModelForm in Django

后端 未结 2 610
我寻月下人不归
我寻月下人不归 2020-12-01 04:39

I would like to make a queryset where the current user is used as a filter in a ModelForm:

class BookSubmitForm(ModelForm):
    book = forms.ModelChoiceField         


        
2条回答
  •  夕颜
    夕颜 (楼主)
    2020-12-01 05:05

    No, the request is not passed to the ModelForm. You'll need to do something like this in your view:

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

    As you said, it's often cleaner to encapsulate this in the Form object, particularly if you have several fields that will need filtered querysets. To do this, override the forms's __init__() and have it accept a kwarg of request:

    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)
    

    Then just pass request whenever you instantiate BookSubmitForm in your view:

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

提交回复
热议问题