djangoのクラスベースのジェネリックビューからModelformにrequest.userオブジェクトを送信

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

質問

したがって、私の目標は、ModeChoicefield QuerysetをModelformのModelChoicefield Querysetをフィルタリングして、リクエストを作成した場所のみを含めることです。

私のモデルフォームは単純です:

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)

ただし、モデルフームのリクエストにアクセスする方法を見つけることができないようです。

私の見解はそうです:

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'を取得しました

これに関するアイデアはありますか?それとも、私のリクエストをモデルフォームに渡す必要なく、モデルチーズフィールドをビューでフィルタリングする方法を考えることができますか?

役に立ちましたか?

解決

キーをポップする必要があります user から kwargsPlaceEventForm.__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+を含む)に対するYujiの回答を更新するには、以下の例を参照してください(更新されたメソッドの署名に注意してください)。 Yujiの提案されたアプローチは、他のビジネスロジックとともにQuerysetをビューに保持し、あらゆる形のクラスを拡張し続けるのに役立ちます 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