Dalvtor
Dalvtor

Reputation: 3286

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?

Upvotes: 9

Views: 2712

Answers (2)

arman
arman

Reputation: 352

Working for me! I can access the request in the Form instance like self.request

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

Upvotes: 0

Bernhard Vallant
Bernhard Vallant

Reputation: 50776

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.

Upvotes: 16

Related Questions