How to get the current model instance from inlineadmin in Django

django, django-admin, python

Solution

If the `person` cannot be easily got from `request`, you may need to manually pass it by overriding `ModelAdmin.get_form()` or `InlineModelAdmin.get_formset()`:

from functools import partial

class MyModelAdmin(admin.ModelAdmin):
    def get_form(self, request, obj=None, **kwargs):
        kwargs['formfield_callback'] = partial(self.formfield_for_dbfield, request=request, obj=obj)
        return super(MyModelAdmin, self).get_form(request, obj, **kwargs)

    def formfield_for_dbfield(self, db_field, **kwargs):
        person = kwargs.pop('obj', None)
        formfield = super(MyModelAdmin, self).formfield_for_dbfield(db_field, **kwargs)
        if db_field.name == "car" and person:
            formfield.queryset = Cars.objects.filter(owner=person)
        return formfield 

# or its inline
class MyInlineModelAdmin(admin.StackedInline):
    def get_formset(self, request, obj=None, **kwargs):
        kwargs['formfield_callback'] = partial(self.formfield_for_dbfield, request=request, obj=obj)
        return super(MyInlineModelAdmin, self).get_formset(request, obj, **kwargs)

    def formfield_for_dbfield(self, db_field, **kwargs):
        person = kwargs.pop('obj', None)
        formfield = super(MyInlineModelAdmin, self).formfield_for_dbfield(db_field, **kwargs)
        if db_field.name == "car" and person:
            formfield.queryset = Cars.objects.filter(owner=person)
        return formfield 

Or

class MyModelAdmin(admin.ModelAdmin):
    def get_form(self, request, obj=None, **kwargs):
        kwargs['formfield_callback'] = partial(self.formfield_for_dbfield, request=request, obj=obj)
        return super(MyModelAdmin, self).get_form(request, obj, **kwargs)

    def formfield_for_dbfield(self, db_field, **kwargs):
        if db_field.name != "car":
            kwargs.pop('obj', None)
        return super(MyModelAdmin, self).formfield_for_dbfield(db_field, **kwargs)

    def formfield_for_manytomany(self, db_field, request=None, **kwargs):
        person = kwargs.pop('obj', None)
        if db_field.name == "car" and person:
            kwargs['queryset'] = Cars.objects.filter(owner=person)
        return super(MyModelAdmin, self).formfield_for_manytomany(db_field, request, **kwargs)

Problem

I am using the `formfield_for_manytomany` given in django documentation. But inside that function I need to get the current parent object being edited. ``` def formfield_for_manytomany(self, db_field, request, **kwargs): if db_field.name == "car": kwargs["queryset"] = Cars.objects.filter(owner=person) return super(myModel, self).formfield_for_manytomany(db_field, request, **kwargs) ``` How can I get the person being edited?

Original source

Related problems