从 Django 中基于类的通用视图将 request.user 对象发送到 ModelForm

发布于 2024-11-03 08:56:03 字数 1148 浏览 0 评论 0原文

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

我的 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?

So, my goal is to be able to filter a ModelChoiceField queryset in my ModelForm to only include Places that request.user has created.

My ModelForm is simply:

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

I'd like to be able to add something like:

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

However, I can't seem to find a way to access the request in the ModelForm.

My View is like so:

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)

I'm not sure if this is even close to what I should do, but I tried:

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

But I got the error: init() got an unexpected keyword argument 'place_user'

Any ideas on this one? Or can anyone think of a way to filter my ModelChoiceField in the view without needing to pass my request to the ModelForm?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

爱你不解释 2024-11-10 08:56:03

您需要在 PlaceEventForm.__init__() 方法中从 kwargs 中弹出关键 user,以防止其转到 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)

You need to pop key user from kwargs in PlaceEventForm.__init__() method, to prevent it from going to ModelForm.__init__() method:

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)
夏有森光若流苏 2024-11-10 08:56:03

我使用的是 iPhone,但这样做:

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

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

I'm on an iPhone, but do this:

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

Wow that was hard! No indention support!

奢欲 2024-11-10 08:56:03

要更新 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

To update Yuji's answer for Django 1.10+ (including Django 2.0+), see the example below (note the updated method signature). Yuji's suggested approach keeps the queryset in the view along with the other business logic, and helps keep any form class extending models.ModelForm clean and straightforward.

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

Shorter:

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文