Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django - How to set the request in the admin form?

I have a form that uses the request object:

class FooForm(forms.ModelForm):

    class Meta:
        model = Foo
        fields = ('title', )

    def __init__(self, *args, **kwargs):
        self.request = kwargs.pop('request')
        super().__init__(*args, **kwargs)

In my views, whenever I want to instantiate the form, it is as easy as doing the following:

class FooCreateView(LoginRequiredMixin, CreateView):
    model = Foo
    form_class = FooForm

    def get_form_kwargs(self):
        kwargs = super(FooCreateView, self).get_form_kwargs()
        kwargs.update({'request': self.request})
        return kwargs

Now, I want to use the same form in the admin panel, so I do the following:

class FooAdmin(admin.ModelAdmin):
    form = FooForm

But Boom! It dies:

KeyError at /admin/foo/foo/add/
'request'

I tried to do the following, but it didn't work

def get_form(self, request, *args,  **kwargs):
    form = super(FooAdmin, self).get_form(request, *args, **kwargs)
    form.request = request
    kwargs['request'] = request
    return form

In summary, is there a way to pass the request to the admin form?

like image 674
Dalvtor Avatar asked Jan 11 '19 17:01

Dalvtor


1 Answers

The get_form() method only returns the class, not an instance of it. The instantiation of the form is hidden in the add_view and change_view methods of the ModelAdmin. You can somehow work your way around that with creating a new form class in the get_form method:

def get_form(self, request, obj=None, **kwargs):

    FooForm = super(FooAdmin, self).get_form(request, obj, **kwargs)

    class RequestFooForm(FooForm):
        def __new__(cls, *args, **kwargs):
            kwargs['request'] = request
            return FooForm(*args, **kwargs)

    return RequestFooForm

Otherwise if you just need access during saving you probably can also have a look at the model admin's save_form and save_model methods.

like image 184
Bernhard Vallant Avatar answered Sep 23 '22 01:09

Bernhard Vallant