[Django]-Passing session data to ModelForm inside of ModelAdmin

2👍

Combining the good ideas in Izz ad-Din Ruhulessin’s answer and the suggestion by Cikić Nenad, I ended up with a very awesome AND concise solution below:

class CustomModelAdmin(admin.ModelAdmin):
    def get_form(self, request, obj=None, **kwargs):
        self.form.request = request #so we can filter based on logged in user for example
        return super(CustomModelAdmin, self).get_form(request,**kwargs)

Then just set a custom form for the modeladmin like:

form = CustomAdminForm

And in the custom modelform class access request like:

self.request #do something with the request affiliated with the form

👤JWL

1👍

Theoretically, you can override the ModelAdmin’s get_form method:

# In django.contrib.admin.options.py
def get_form(self, request, obj=None, **kwargs):
    """
    Returns a Form class for use in the admin add view. This is used by
    add_view and change_view.
    """
    if self.declared_fieldsets:
        fields = flatten_fieldsets(self.declared_fieldsets)
    else:
        fields = None
    if self.exclude is None:
        exclude = []
    else:
        exclude = list(self.exclude)
    exclude.extend(kwargs.get("exclude", []))
    exclude.extend(self.get_readonly_fields(request, obj))
    # if exclude is an empty list we pass None to be consistant with the
    # default on modelform_factory
    exclude = exclude or None
    defaults = {
        "form": self.form,
        "fields": fields,
        "exclude": exclude,
        "formfield_callback": curry(self.formfield_for_dbfield, request=request),
    }
    defaults.update(kwargs)
    return modelform_factory(self.model, **defaults)

Note that this returns a form class and not a form instance.

1👍

If some newbie, as myself, passes here:
I had to define:

class XForm(forms.ModelForm):    
    request=None    

then at the end of the previous post

    mfc=modelform_factory(self.model, **defaults)   
    self.form.request=request   #THE IMPORTANT statement   
    return mfc

0👍

i use queryset fot filtering records, maybe this example help you:

.....
.....
def queryset(self, request):
    cuser = User.objects.get(username=request.user)

    qs = self.model._default_manager.get_query_set()
    ordering = self.ordering or () # otherwise we might try to *None, which is bad ;)

    if ordering:
        qs = qs.order_by(*ordering)

    qs = qs.filter(creator=cuser.id)

    return qs
👤Saff

0👍

Here is a production/thread-safe variation from nemesisfixx solution:

def get_form(self, request, obj=None, **kwargs):
    class NewForm(self.form):
        request = request
    return super(UserAdmin, self).get_form(request, form=NewForm, **kwargs)

0👍

class CustomModelAdmin(admin.ModelAdmin):

    def get_form(self, request, obj=None, **kwargs):
        get_form = super(CustomModelAdmin, self).get_form(request,**kwargs)
        get_form.form.request = request
        return get_form

Now in ModelForm, we can access it by

self.request

Example:

class CustomModelForm(forms.ModelForm):

    def __init__(self, *args, **kwargs):
        super(TollConfigInlineForm, self).__init__(*args, **kwargs)
        request = self.request
        user = request.user

Leave a comment