As you know we can define a ModelForm and then replace add and change forms by setting form attribute in modelAdmin class. for example:
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
in a simple view we can initialize a form object and pass extra arguments to init function of the form. something like this:
def my_view(request):
form = FooAdminForm(p1='aaa', p2='bbb')
and then in the init function we can access these parameter.
self.p1 = kwargs.pop('p1')
self.p2 = kwargs.pop('p2')
but how can I pass arguments to modelAdmin form? I can only pass form class to modelAdmin form attribute, and I can't initialize it like in views.
I found a solution on stackoverflow here:
Use a form with a custom __init__ in Django Admin
but it adds a dynamic attribute to form object, which I think is a little hackish. Is there a better or formal way for doing this?
I was looking around for a solution to this, and found a kinda-elegant solution in Django's issue tracker:
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
So if you're using a custom form, you can simply pass it to super().get_form()
using 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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With