Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to display an attribute of a foreign key in the Django admin page

I want to display the level field of the category to which the product is related on the object's admin page.

    class Category(models.Model):
        name = models.CharField(max_length=50, default=False)
        level = models.IntegerField(help_text="1, 2 ,3 or 4")

    class Product(models.Model):
        category = models.ForeignKey(Category)
        name = models.CharField(max_length=100)


        prepopulated_fields = {'slug': ('name',)}
        fieldsets = [
            ('Product Info',{'fields': ['name', 'slug','partno','description']}),
            ('Categorisation',{'fields': ['brand','category']}),

I have found references to list_filter, but nothing regarding how to show the field.

Does anyone know how to do this?

like image 378
bytejunkie Avatar asked Aug 10 '11 10:08

bytejunkie


People also ask

How does Django store foreign key values?

Note that the _id in the artist parameter, Django stores foreign keys id in a field formed by field_name plus _id so you can pass the foreign key id directly to that field without having to go to the database again to get the artist object.

How does foreign key work in Django?

What is ForeignKey in Django? ForeignKey is a Field (which represents a column in a database table), and it's used to create many-to-one relationships within tables. It's a standard practice in relational databases to connect data using ForeignKeys.


4 Answers

Define a method on the ModelAdmin class which returns the value of the related field, and include that in list_display.

class ProductAdmin(admin.ModelAdmin):
    list_display = ('name', 'level')
    model = Product

    def level(self, obj):
        return obj.category.level
like image 78
Daniel Roseman Avatar answered Nov 15 '22 02:11

Daniel Roseman


To show the related field in a ModelAdmin's fieldset, the field must first be declared in readonly_fields.

  1. Define a method that returns the desired value.

  2. Include the method or its name in readonly_fields.

  3. Include the method or its name in its fieldset's "fields" list.

from django.contrib import admin
from .models import MyModel

@admin.register(MyModel)
class MyModelAdmin(admin.ModelAdmin):
    readonly_fields = ['get_parent_name']  # Don't forget this!
    fieldsets = [('Parent info', {'fields': ['get_parent_name']} )]
    
    @admin.display(description='Parent')
    def get_parent_name(self, obj):
        return obj.parent.name

On the Change page, there will be a "Parent info" section with the object's parent's name.

like image 28
pphysch Avatar answered Nov 15 '22 02:11

pphysch


In your admin.py file

class ProductAdmin(admin.ModelAdmin):
    list_display = ('name', 'category__level', 'category')

admin.site.register(Product, ProductAdmin)

Try this.............

like image 35
Priyank Patel Avatar answered Nov 15 '22 03:11

Priyank Patel


The simplest way is to put the level of the Category into the __unicode__ method:

class Category(models.Model):
    name = models.CharField(max_length=50, default=False)
    level = models.IntegerField(help_text="1, 2 ,3 or 4")

    def __unicode__(self):
        return u'%s [%d]' % (self.name, self.level)

So the select box will show it.

like image 41
rewritten Avatar answered Nov 15 '22 02:11

rewritten