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
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…