简体   繁体   中英

Django: How to display foreign key value in admin form

How do I get the admin form to display the foreign key value in the drop down list of a django admin form rather than display 'table name object'? I am struggling to work this out.

Here are examples of my model code (Both contain the catname field. catname is PK in Parent and FK in Child).

Parent(models.Model):
catname = models.CharField(db_column='catname', primary_key=True, max_length=255, verbose_name="catname")  
description = models.CharField(db_column='Description', max_length=255, blank=True, null=True)

class Meta:
    managed = False
    db_table = 'Parent'
    verbose_name_plural = ('Parent')

    #def __unicode__(self): return self.catname.catname
    def __str__(self):
        return '%s' % (self.catname)



class Child(models.Model):
    description = models.CharField(db_column='VarDescription', max_length=255, blank=True, null=True)  
    cname = models.CharField(db_column='VarName', primary_key=True, max_length=255) 
    catname = models.ForeignKey(Parent, db_column='catname', blank=True, null=True) 
    def __unicode__(self):
        return self.name
    def child_cat(self):
        return self.catname.catname
    class Meta:
        managed = False
        db_table = 'Child'
        verbose_name_plural = ('Child')

Admin looks like:

from django.contrib import admin

from Library.models import Parent, Child
# Register your models here.

class ChildAdmin(admin.ModelAdmin):
    list_display = ('cname','description','child_cat')
    fields=('cname','description','child_cat')
    search_fields = ('cname','description')
    ordering = ('cname',)

admin.site.register(Child,ChildAdmin)

You can override the form used by ModelAdmin or even change just one field with ModelAdmin.formfield_overrides .

Read the documentation here

The admin select widget is displaying the __unicode__() method of the related model. You could override the __unicode__() method to display the key, but that might not be the best way to go about it since it will appear everywhere else __unicode__() is used.

If you are using a ModelAdmin, one option is to define a callable in your ModelAdmin which returns the value you'd like to see, and add that callable to your ModelAdmin's list_display . For example, if your model is Book and you'd like to see the foreign key value of Author , you could do this:

class BookAdmin(ModelAdmin):
    def author_pk(self, obj):
        return self.author.pk

    list_display = (
        'name',
        'author_pk',
    )

Another option is to use the ModelAdmin.raw_id_fields attribute, however this will change the default behavior of the widget to an Input instead of a Select.

The problem was probably connected with allowing null and blank values in catname. After an hour's search it finally dawned on me why the code that worked for everyone else (but OP) didn't work for me. I got around it with a simple try/except:

appname/admin.py

from django.contrib import admin
from . import models


    class BookAdmin(ModelAdmin):
        list_display = ('name', 'date', 'andwhatnot', 'author_variable')

        def author_variable(self, obj):
            try:
                return self.author.blankablevariable
            except:
                pass

admin.site.register(models.Book, BookAdmin)

Hope it helps someone who has the same problem. If using pass in except is something frowned upon - I'll be glad to hear. Saying I'm new is an overstatement.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM