如何将额外的参数传递给django管理员自定义表单?

时间:2016-08-07 06:39:36

标签: django django-admin

如您所知,我们可以定义ModelForm,然后通过在modelAdmin类中设置form属性来替换添加和更改表单。例如:

class FooAdminForm(django.forms.ModelForm):
     class Meta:
         model = Foo

     def __init__(self, *args, **kwargs):
         super(FooAdminForm, self).__init__(self, *args, **kwargs)


class FooAdmin(admin.ModelAdmin):
    form = FooAdminForm

在一个简单的视图中,我们可以初始化一个表单对象,并将额外的参数传递给表单的 init 函数。像这样的东西:

def my_view(request):
    form = FooAdminForm(p1='aaa', p2='bbb')

然后在 init 函数中我们可以访问这些参数。

self.p1 = kwargs.pop('p1')
self.p2 = kwargs.pop('p2')

但是如何将参数传递给modelAdmin表单?我只能将表单类传递给modelAdmin表单属性,我不能像在视图中那样初始化它。

我在这里找到了stackoverflow的解决方案:

Use a form with a custom __init__ in Django Admin

但是它为表单对象添加了一个动态属性,我认为这有点像hackish。这样做有更好或正式的方法吗?

2 个答案:

答案 0 :(得分:1)

由于ModelAdmin.get_form的行为与FormView.get_form不太相同,因此您需要稍稍偷偷摸摸:

https://docs.djangoproject.com/en/3.0/ref/contrib/admin/#django.contrib.admin.ModelAdmin.get_form

class FooAdmin(admin.ModelAdmin):
    form = FooAdminForm

    def get_form(self, request, obj=None, **kwargs):
        form_class = super().get_form(request, obj, **kwargs)
        class Form(form_class):
            def __init__(self, *args, **kwargs):
                kwargs.update(foo='bar')
                super().__init__(self, *args, **kwargs)
        return Form

答案 1 :(得分:0)

我一直在寻找解决方案,并在Django的问题跟踪器中找到了一种优雅的解决方案:

def get_form(self, request, obj=None, **kwargs):
    Form = super().get_form(request, obj=None, **kwargs)
    return functools.partial(Form, user=request.user)

https://code.djangoproject.com/ticket/27240#comment:9

因此,如果您使用的是自定义表单,只需使用super().get_form()将其传递到kwargs

def get_form(self, request, obj=None, **kwargs):
    kwargs['form'] = FooAdminForm
    Form = super().get_form(request, obj=None, **kwargs)
    return functools.partial(Form, user=request.user)