Отправка request.user объект Modelform из общего представления на основе класса в Django

StackOverflow https://stackoverflow.com/questions/5806224

Вопрос

Таким образом, моя цель - иметь возможность отфильтровать запрос моделей -профиля в мою модульформ, чтобы включить только места, которые создал request.user.

Мой модоформ просто:

class PlaceEventForm(models.ModelForm):
    class Meta:
        model = Event

Я бы хотел добавить что -то вроде:

def __init__(self, *args, **kwargs):
    super(PlaceEventForm, self).__init__(*args, **kwargs)
    self.fields['place'].queryset = Place.objects.filter(created_by=request.user)

Тем не менее, я не могу найти способ получить доступ к запросу в Modelform.

Мой взгляд такой:

class PlaceEventFormView(CreateView):
    form_class = PlaceEventForm
    template_name = 'events/event_create.html'

    @method_decorator(login_required)
    def dispatch(self, *args, **kwargs):
        return super(PlaceEventFormView, self).dispatch(*args, **kwargs)

Я не уверен, что это даже близко к тому, что я должен сделать, но я попробовал:

def get_form_kwargs(self):
    kwargs = super(PlaceEventFormView, self).get_form_kwargs()
    kwargs.update({'place_user': self.request.user})
    return kwargs

Но я получил ошибку: в этом() Получил неожиданный аргумент ключевого слова 'place_user'

Есть идеи на этом? Или кто -нибудь может придумать способ отфильтровать мое моделькофилд в представлении без необходимости передать мою просьбу в Modelform?

Это было полезно?

Решение

Вам нужно выпить ключ user из kwargs в PlaceEventForm.__init__() метод, чтобы не добраться до ModelForm.__init__() Метод:

views.py:

class PlaceEventFormView(CreateView):
    form_class = PlaceEventForm
    template_name = 'events/event_create.html'

    @method_decorator(login_required)
    def dispatch(self, *args, **kwargs):
        return super(PlaceEventFormView, self).dispatch(*args, **kwargs)

    def get_form_kwargs(self):
        kwargs = super(PlaceEventFormView, self).get_form_kwargs()
        kwargs.update({'place_user': self.request.user})
        return kwargs

forms.py:

class PlaceEventForm(models.ModelForm):
    class Meta:
        model = Event

    def __init__(self, *args, **kwargs):
        user = kwargs.pop('place_user')
        # now kwargs doesn't contain 'place_user', so we can safely pass it to the base class method
        super(PlaceEventForm, self).__init__(*args, **kwargs)
        self.fields['place'].queryset = Place.objects.filter(created_by=user)

Другие советы

Я на iPhone, но делай это:

def get_form(self, form_class):
     form = super(MyView, self).get_form(form_class)
     form.fields['place'].querset = Place....
     return form

Вау, это было тяжело! Без поддержки недостатки!

Чтобы обновить ответ Юджи для Django 1.10+ (включая Django 2.0+), см. Пример ниже (обратите внимание на подпись обновленного метода). Предлагаемый подход Юджи сохраняет керизет в взгляде вместе с другой бизнес -логикой и помогает сохранить любой класс формы. models.ModelForm Чистый и простой.

def get_form(self, form_class=None):
    if form_class is None:
        form_class = self.get_form_class()
    form = super(MyView, self).get_form()
    form.fields['place'].queryset = Place.objects.filter(created_by=self.request.user)
    return form

Короче:

def get_form(self, form_class=None):
    form = super(MyView, self).get_form(form_class)
    form.fields['place'].queryset = Place.objects.filter(created_by=self.request.user)
    return form
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top