Django:从管理员的 form.clean() 访问请求对象
My question is very similar to this one: How do I access the request object or any other variable in a form's clean() method?
Except, I have the same problem with admin form. So I can't see a way to init the form myself, therefore - to pass a request to it.
Thanks beforehand.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
确实,有一种方法可以解决您的问题!
您将需要子类化由
ModelAdmin.get_form()
提供的 form 并覆盖它:Indeed, there is a way to solve your issue!
You will need to subclass form provided by
ModelAdmin.get_form()
and override it:这个解决方案对我有用。您可以在表单中的任何位置使用
self.request
来使用它,包括def clean(self)
This solution works for me. You can use
self.request
anywhere in the form to use it, includingdef clean(self)
ModelAdmin 类中有许多挂钩可以让您执行此操作 - 请查看 django.contrib.admin.options 中的代码。
ModelAdmin.save_form
和ModelAdmin.save_model
这两个方法可能对您有帮助,这两个方法都传递请求对象。因此,您可以在 Admin 子类中重写这些方法并执行您需要的任何额外处理。评论后编辑
您说得很对,这不会让您根据用户的权限验证表单。不幸的是,表单实例化深深地埋藏在
ModelAdmin
的add_view
和change_view
方法中。如果不复制大量现有代码,就没有太多可能性。您可以重写
*_view
方法;或者您可以尝试重写 modelform_factory 函数以返回一个已嵌入请求对象的新类;或者您可以尝试摆弄表单类__new__
方法来执行相同的操作,但由于表单元类,这很棘手。There are a number of hooks in the
ModelAdmin
class to allow you to do things this - look at the code indjango.contrib.admin.options
.Two methods that might help you are
ModelAdmin.save_form
andModelAdmin.save_model
, both of which are passed the request object. So you can override these methods in your Admin subclass and do any extra processing you need.Edited after comment
You're quite right that this won't let you validate the form dependent on the user's privileges. Unfortunately the form instantiation is buried deep within the
add_view
andchange_view
methods ofModelAdmin
.There aren't many possibilities without duplicating a lot of existing code. You could override the
*_view
methods; or you could try and override themodelform_factory
function to return a new class with the request object baked in already; or you could try fiddling with the form class__new__
method to do the same thing, but that's tricky because of the form metaclass.