如何在表单的clean()方法中访问请求对象或其他变量?
我想在一个表单的清理方法中使用请求的用户信息,但我该怎么获取请求对象呢?我可以修改这个清理方法,让它接受一些变量输入吗?
12 个回答
36
更新于2011年10月25日: 现在我使用的是动态创建的类,而不是方法,因为Django 1.3在其他情况下会出现一些奇怪的问题。
class MyModelAdmin(admin.ModelAdmin):
form = MyCustomForm
def get_form(self, request, obj=None, **kwargs):
ModelForm = super(MyModelAdmin, self).get_form(request, obj, **kwargs)
class ModelFormWithRequest(ModelForm):
def __new__(cls, *args, **kwargs):
kwargs['request'] = request
return ModelForm(*args, **kwargs)
return ModelFormWithRequest
接着,按照下面的方式重写 MyCustomForm.__init__
:
class MyCustomForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
self.request = kwargs.pop('request', None)
super(MyCustomForm, self).__init__(*args, **kwargs)
这样,你就可以在 ModelForm
的任何方法中通过 self.request
来访问请求对象。
47
如果你在使用基于类的视图,而不是基于函数的视图,那么在你的编辑视图中,可以重写get_form_kwargs
。下面是一个自定义的创建视图(CreateView)的示例代码:
from braces.views import LoginRequiredMixin
class MyModelCreateView(LoginRequiredMixin, CreateView):
template_name = 'example/create.html'
model = MyModel
form_class = MyModelForm
success_message = "%(my_object)s added to your site."
def get_form_kwargs(self):
kw = super(MyModelCreateView, self).get_form_kwargs()
kw['request'] = self.request # the trick!
return kw
def form_valid(self):
# do something
上面的视图代码会让request
作为一个关键字参数传递给表单的__init__
构造函数。因此在你的ModelForm
中,你可以这样做:
class MyModelForm(forms.ModelForm):
class Meta:
model = MyModel
def __init__(self, *args, **kwargs):
# important to "pop" added kwarg before call to parent's constructor
self.request = kwargs.pop('request')
super(MyModelForm, self).__init__(*args, **kwargs)
183
Ber的回答——把它存储在线程局部变量中——其实是个很糟糕的主意。这样做完全没有必要。
一个更好的方法是重写表单的 __init__
方法,增加一个额外的关键字参数 request
。这样可以把请求存储在 表单 中,这样就能在需要的地方使用,并且可以在你的清理方法中访问它。
class MyForm(forms.Form):
def __init__(self, *args, **kwargs):
self.request = kwargs.pop('request', None)
super(MyForm, self).__init__(*args, **kwargs)
def clean(self):
... access the request object via self.request ...
然后在你的视图中:
myform = MyForm(request.POST, request=request)