How do I get the actual object id in a Django admin page (inside formfield_for_foreignkey)?

After some digging around, we were able to grab the arguments that get passed to the admin view (after being parsed by django admin's urls.py) and use that (self_pub_id) to grab the object:

class PublicationAdmin(admin.ModelAdmin):

    def formfield_for_manytomany(self, db_field, request, **kwargs):
        if db_field.name == "authors":
            #this line below got the proper primary key for our object of interest
            self_pub_id = request.resolver_match.args[0]

            #then we did some stuff you don't care about
            pub = Publication.objects.get(id=self_pub_id)
            kwargs["queryset"] = pub.authors.all()
        return super(PublicationAdmin, self).formfield_for_manytomany(db_field, request, **kwargs)

A more elegant solution is to use the accepted answers recomendation and leverage the get_form ModelAdmin member function. Like so:

class ProfileAdmin(admin.ModelAdmin):
    my_id_for_formfield = None
    def get_form(self, request, obj=None, **kwargs):
        if obj:
            self.my_id_for_formfield = obj.id
        return super(ProfileAdmin, self).get_form(request, obj, **kwargs)

    def formfield_for_foreignkey(self, db_field, request, **kwargs):
        if db_field.name == "person":
            kwargs["queryset"] = Person.objects.filter(profile=self.my_id_for_formfield)
        return super(ProfileAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)

As far as i know it is not possible to access the current instance through the formfield_for_...-methods, because they will only be called for a single field instance!

A better point to hook into this logic where you can access the whole instance/form would be get_form. You can also overwrite a form field's queryset there!


I made it work by rewrite change_view()

class CartAdmin(admin.ModelAdmin):

def change_view(self, request, object_id, form_url='', extra_context=None):
    self.object_id = object_id
    return self.changeform_view(request, object_id, form_url, extra_context)


def formfield_for_foreignkey(self, db_field, request, **kwargs):
    print self.object_id
    return super(CartAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)

then you can call self.object_id inside formfield_for_foreignkey()