Foreign Key Reference for Django in Admin
Asked Answered
A

1

7

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).
Agoraphobia answered 1/10, 2015 at 8:39 Comment(1)
What is get_author_description?Surculose
S
9

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"
Surculose answered 1/10, 2015 at 8:46 Comment(6)
Hmm, I added the lines and it is still throwing me the error. Am I doing something wrong? <class 'blog.admin.PostAdmin'>: (admin.E108) The value of 'list_display[2]' refers to 'author_description', which is not a callable, an attribute of 'PostAdmin', or an attribute or method on 'blog.Post'.Agoraphobia
Post Edited. Please read and update your code. author_description was not correctly indented.Septal
I got it! I will make changes to the post to make it all clear. It all makes sense now, @LuisMasuelli. The author_description should be a def within the PostAdmin class or it will not be able to identify the method. I shall add one more thing. The last line should be return obj.author.get_author_description() because the description is in the Author class, not the Post. I caught it during running the server.Agoraphobia
@bryansis2010 having get_author_description as a method name in author seems to violate DRYKussell
Agree with you @Foon, I will take that into account when drafting the edited answer.Agoraphobia
how can i make sure these fields can be referenced in the queryset for an admin actionTucana

© 2022 - 2024 — McMap. All rights reserved.