从Django中基于类的通用视图向ModelForm发送request.user对象
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从Django中基于类的通用视图向ModelForm发送request.user对象相关的知识,希望对你有一定的参考价值。
因此,我的目标是能够在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?
答案
你需要在user
方法中从kwargs
弹出关键PlaceEventForm.__init__()
,以防止它进入ModelForm.__init__()
方法:
views.朋友:
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.朋友:
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
哇,这很难!没有缩进支持!
另一答案
要更新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
以上是关于从Django中基于类的通用视图向ModelForm发送request.user对象的主要内容,如果未能解决你的问题,请参考以下文章
从 Django 中基于类的通用视图自定义表单变量的首选方法是啥?