【发布时间】:2011-02-10 15:20:22
【问题描述】:
我的问题和这个很相似:How do I access the request object or any other variable in a form's clean() method?
除了,我对管理表单有同样的问题。所以我看不到自己初始化表单的方法,因此 - 将请求传递给它。
先谢谢了。
【问题讨论】:
标签: django django-admin django-forms
我的问题和这个很相似:How do I access the request object or any other variable in a form's clean() method?
除了,我对管理表单有同样的问题。所以我看不到自己初始化表单的方法,因此 - 将请求传递给它。
先谢谢了。
【问题讨论】:
标签: django django-admin django-forms
确实有办法解决您的问题!
您将需要 ModelAdmin.get_form() 提供的 subclass form 并覆盖它:
class BusinessDocumentCommentForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
self.request = kwargs.pop('request', None)
# Voila, now you can access request anywhere in your form methods by using self.request!
super(BusinessDocumentCommentForm, self).__init__(*args, **kwargs)
if self.request.GET.get('document_pk', False):
#Do something
def clean(self):
# Do something with self.request
# etc.
class Meta:
model = BusinessDocumentComment
class BusinessDocumentCommentAdmin(admin.ModelAdmin):
form = BusinessDocumentCommentForm
def get_form(self, request, obj=None, **kwargs):
AdminForm = super(BusinessDocumentCommentAdmin, self).get_form(request, obj, **kwargs)
class AdminFormWithRequest(AdminForm):
def __new__(cls, *args, **kwargs):
kwargs['request'] = request
return AdminForm(*args, **kwargs)
return AdminFormWithRequest
【讨论】:
ModelAdmin 类中有许多钩子可让您执行此操作 - 请查看 django.contrib.admin.options 中的代码。
ModelAdmin.save_form 和ModelAdmin.save_model 这两个方法可能对您有所帮助,这两个方法都传递了请求对象。因此,您可以在 Admin 子类中覆盖这些方法并执行您需要的任何额外处理。
评论后编辑
你说得对,这不会让你根据用户的权限来验证表单。不幸的是,表单实例化深埋在ModelAdmin 的add_view 和change_view 方法中。
如果不复制大量现有代码,可能性并不大。您可以覆盖 *_view 方法;或者您可以尝试覆盖modelform_factory 函数以返回一个新类,其中已经包含请求对象;或者您可以尝试使用表单类 __new__ 方法来做同样的事情,但由于表单元类,这很棘手。
【讨论】:
这个解决方案对我有用。你可以在表单的任何地方使用self.request来使用它,包括def clean(self)
class MyModelAdmin(admin.ModelAdmin):
form = MyForm
def get_form(self, request, *args, **kwargs):
form = super(MyModelAdmin, self).get_form(request, *args, **kwargs)
form.request = request
return form
【讨论】:
还有另一种可能性:在您看来,覆盖get_form_kwargs 并添加request:
class FilesUploadCreateView(LoginRequiredMixin, generic.CreateView):
def get_form_kwargs(self):
result = super().get_form_kwargs()
result['request'] = self.request
return result
现在在你的表单中,当它被创建时,记住它,所以,在这个特定Form 类的所有方法中,你将能够通过self.request 访问请求属性:
class UploadFilesForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
self.request = kwargs.pop('request')
super().__init__(*args, **kwargs)
现在您可以使用self.request 访问表单中的任何位置!
【讨论】:
get_form_kwargs,因为他想处理管理面板的更改。
kwargs 中添加了一个变量,当它被实例化时,我“弹出”了request 变量。没有任何问题(除非得到证明),我的回答也没有什么不妥,而且它工作得完美无缺。