17

因此,我的目标是能够在我的 ModelForm 中过滤 ModelChoiceField 查询集,以仅包含 request.user 创建的 Places。

我的 ModelForm 很简单:

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

但我得到了错误:init()得到了一个意外的关键字参数'place_user'

关于这个有什么想法吗?或者任何人都可以想出一种方法来过滤视图中的 ModelChoiceField 而无需将我的请求传递给 ModelForm?

4

3 回答 3

27

您需要user从方法kwargs中弹出键PlaceEventForm.__init__(),以防止它进入ModelForm.__init__()方法:

视图.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

表格.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)
于 2011-04-27T16:31:26.717 回答
2

我在 iPhone 上,但是这样做:

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

哇,太难了!不支持缩进!

于 2011-04-27T17:26:05.157 回答
1

要更新 Yuji 对 Django 1.10+(包括 Django 2.0+)的回答,请参见下面的示例(注意更新的方法签名)。Yuji 建议的方法将查询集与其他业务逻辑一起保留在视图中,并有助于保持任何表单类的扩展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
于 2018-03-03T05:01:54.233 回答