Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Foreign Key Reference for Django in Admin

I have been trying to solve this issue in Django admin but still cannot find the documentation.

In my models.py, I have the following code:

from django.db import models

class Post(models.Model):
  title = models.CharField(max_length=200)
  author = models.ForeignKey('Author', blank=False)

class Author(models.Model):
  first_name = models.CharField('First Name',max_length=50)
  last_name = models.CharField('Last Name', max_length=50, blank=True)
  description = models.CharField(max_length=500, blank=True)

  def __str__(self):
    return (self.first_name + ' ' + self.last_name)

and in admin.py from django.contrib import admin

# Register your models here.
from .models import Author, Post

class PostAdmin(admin.ModelAdmin):
  list_display = ['title', 'author', 'get_author_description']

admin.site.register(Post, PostAdmin)

However, every time I run the server, I have been getting the error

<class 'blog.admin.PostAdmin'>: (admin.E108) The value of         
'list_display[2]' refers to 'get_author_description', which is not a 
callable, an attribute of 'PostAdmin', or an attribute or method on 
'blog.Post'.

I have been reading a lot of documentation about this but still to no avail. Any takers?

FINAL EDIT I have decided to keep the initial post with the question. The final solution only involves the change in PostAdmin.

class PostAdmin(admin.ModelAdmin):
    list_display = ['title', 'author', 'author_description',]

    def author_description(self, obj):
        return obj.author.description
        author_description.short_description = 'The Author Description'

The key things to take note of are:

  • The method author_description needs to be in the same indentation as the class. Also, it needs to return obj.author.description as we are referring to the author object. get_author_description is not required at all (you can say it was a distraction).
like image 327
bryan.blackbee Avatar asked Oct 01 '15 08:10

bryan.blackbee


1 Answers

You can use a custom method in the admin class as:

class PostAdmin(admin.ModelAdmin):

    list_display = ['title', 'author', 'author_description']

    def author_description(self, obj):
        return obj.author.get_author_description()

Additionally, you can custom format a field or a property within the custom method. If the method would return HTML, you could add the following, after the method, in the class:

author_description.allow_tags = True

Last, if you would like to add a custom verbose name for this method:

author_description.short_description = "My awesome name"
like image 80
Wtower Avatar answered Oct 20 '22 15:10

Wtower