[Fixed]-Inline-like solution for Django Admin where Admin contains ForeignKey to other model


Completing @John’s answer from above – define what you would like to see on the your changelist:

return '<a href="%s">%s</a>' % (
                     reverse('admin:applabel_customer_change', (self.customer.id,)),
                     self.customer.name # add more stuff here

And to add this to the change form, see: Add custom html between two model fields in Django admin's change_form



There is no easy way to do this with django. The inlines are designed to follow relationships backwards.

Potentially the best substitute would be to provide a link to the user object. In the list view this is pretty trivial:

Add a method to your appointment model like:

def customer_admin_link(self):
    return '<a href="%s">Customer</a>' % reverse('admin:app_label_customer_change %s') % self.id
customer_admin_link.allow_tags = True
customer_admin_link.short_description = 'Customer'

Then in your ModelAdmin add:

list_display = (..., 'customer_admin_link', ...)

Another solution to get exactly what you’re looking for at the cost of being a bit more complex would be to define a custom admin template. If you do that you can basically do anything. Here is a guide I’ve used before to explain:

Basically copy the change form from the django source and add code to display the customer information.



In the ModelAdmin class for your Appointments, you should declare the following method:

class MySuperModelAdmin(admin.ModelAdmin):
  def get_form(self, request, obj=None, **kwargs):

    if obj:
      # create your own model admin instance here, because you will have the Customer's
      # id so you know which instance to fetch
      # something like the following
      inline_instance = MyModelAdminInline(self.model, self.admin_site)
      self.inline_instances = [inline_instance]

    return super(MySuperModelAdmin, self).get_form(request, obj, **kwargs)

For more information, browser the source for that function to give you an idea of what you will have access to.



There is a library you can use it.

But if you want to use link to object in showing table you can like this code:

def customer_link(self, obj):
    if obj.customer:
        reverse_link = 'admin:%s_%s_change' % (
            obj.customer._meta.app_label, obj.customer._meta.model_name)
        link = reverse(reverse_link, args=[obj.customer.id])
        return format_html('<a href="%s">More detail</a>' % link)
    return format_html('<span >-</span>')

customer_link.allow_tags = True
customer_link.short_description = 'Customer Info'

And in list_display:

list_display = (...,customer_link,...)

Leave a comment