Как использовать запрос в ModelForm в Django - PullRequest
18 голосов
/ 13 января 2012

Я хотел бы создать набор запросов, где текущий пользователь используется в качестве фильтра в ModelForm:

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

Передает ли Django запрос в форму? Это хорошая практика? Как я могу использовать запрос? (конечно, запрос имени не определен)

Edit:

Я попробовал другое решение, которое заключается в вызове формы в представлении, передавая ей запрос:

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 ]

32 голосов
/ 13 января 2012

Нет, запрос не передается в ModelForm.Вам нужно будет сделать что-то вроде этого в своем представлении:

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

Как вы сказали, часто бывает удобнее инкапсулировать это в объекте Form, особенно если у вас есть несколько полей, которые будут нуждаться в отфильтрованных наборах запросов.Чтобы сделать это, переопределите __init__() формы и примите ее kwarg 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)

Затем просто передайте запрос всякий раз, когда вы создаете экземпляр 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
2 голосов
/ 10 марта 2018

Расширение Ответ AdamKG на представления на основе классов - переопределите метод 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)
        ...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...