Django:从admin的form.clean()访问请求对象

e0bqpujr  于 2023-10-21  发布在  Go
关注(0)|答案(3)|浏览(111)

我的问题和这个很相似:How do I access the request object or any other variable in a form's clean() method?
除了,我有同样的问题与管理形式。因此,我看不到自己初始化表单的方法-向它传递请求。
先谢谢你了。

1wnzp6jl

1wnzp6jl1#


您需要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
xxls0lw8

xxls0lw82#

这个解决方案对我有效。您可以在表单中的任何地方使用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
e7arh2l6

e7arh2l63#

ModelAdmin类中有许多钩子允许你这样做--看看django.contrib.admin.options中的代码。
有两个方法可能会对您有所帮助:ModelAdmin.save_formModelAdmin.save_model,这两个方法都传递了请求对象。因此,您可以在Admin子类中覆盖这些方法,并执行所需的任何额外处理。

评论后编辑

您说得很对,这不会让您根据用户的权限来验证表单。不幸的是,表单示例化被深埋在ModelAdminadd_viewchange_view方法中。
如果不复制大量现有代码,就没有太多的可能性。您可以重写*_view方法;或者你可以尝试覆盖modelform_factory函数,返回一个新的类,其中已经包含了request对象;或者你可以尝试摆弄表单类__new__方法来做同样的事情,但这很棘手,因为表单元类。

相关问题