如何将额外的参数传递给 django admin 自定义表单?
Posted
技术标签:
【中文标题】如何将额外的参数传递给 django admin 自定义表单?【英文标题】:How to pass an extra argument to django admin custom form? 【发布时间】:2016-12-13 04:35:06 【问题描述】:如您所知,我们可以定义一个 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表单属性,不能像在视图中那样初始化它。
我在这里找到了关于 *** 的解决方案:
Use a form with a custom __init__ in Django Admin
但它为表单对象添加了一个动态属性,我认为这有点骇人听闻。有没有更好或更正式的方式来做到这一点?
【问题讨论】:
你有没有找到更好的方法? 使用functools.partial
比设置类属性要好,但仍然很麻烦:(
@djvg 这个答案也解决了这个问题并且有很多赞成票。 ***.com/questions/2683689/…
but it adds a dynamic attribute to form object
— 这是正确的做法。
【参考方案1】:
我一直在寻找解决方案,并在 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
因此,如果您使用的是自定义表单,您只需使用 kwargs
将其传递给 super().get_form()
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)
【讨论】:
【参考方案2】:因为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
【讨论】:
错误是modelform_factory() got an unexpected keyword argument 'foo'
,因为get_form
初始化了modelform_factory 并提供了ModelForm
class,而不是实例。 docs
啊,我的错。 ModelAdmin.get_form
的行为与 View.get_form
不同...
您也许可以使用functools.partial
将关键字参数添加到super().get_form(...)
的结果中,但这有点笨拙...
不适合我,我得到 AttributeError: Form' object has no attribute 'get'。在 Django 2.2 上,但我不认为这有什么不同。
gabn88: 你确定你输入正确吗?我的回答中没有.get()
电话,只有.get_form
。以上是关于如何将额外的参数传递给 django admin 自定义表单?的主要内容,如果未能解决你的问题,请参考以下文章