How to use the request in a ModelForm in Django

后端 未结 2 611
我寻月下人不归
我寻月下人不归 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
    
    0 讨论(0)
  • 2020-12-01 05:11

    Extending AdamKG answer to class based views - override the get_form_kwargs method:

    class PassRequestToFormViewMixin:
        def get_form_kwargs(self):
            kwargs = super().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
    

    and then in forms:

    from django.forms import ModelForm
    class BookSubmitForm(ModelForm):
        def __init__(self, *args, **kwargs):
            self.request = kwargs.pop("request")
            super().__init__(*args, **kwargs)
            ...
    
    0 讨论(0)
提交回复
热议问题