Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to override default display values for a select field for foreign keys in the Django Admin?

I'm creating models, where each model should be related with a user, like this:

class Item(models.Model):
    user = models.ForeignKey(User)

But then in the Django Admin, for an Item, it shows a select field with all the users listed by their usernames. In addition to their usernames, I also need to display each user's first_name and last_name.

How can all three fields be displayed together within that select list in the Django Admin interface?

like image 390
rush Avatar asked May 04 '13 00:05

rush


2 Answers

You need to create custom Form for this and set form attribute in your ModelAdmin.

In that Form you will need to override form field type of user field on model to custom ModelChoiceField.

ModelChoiceField has a method called label_from_instance, you need to override that to get full name.

Example code

######################################
## models.py ##
######################################

from django.db import models
from django.contrib.auth.models import User

class Item(models.Model):
    user = models.ForeignKey(User)
    name = models.CharField("name", max_length=60)

    def __unicode__(self):
        return self.name

######################################
## forms.py ##
######################################

from django import forms
from django.contrib.auth.models import User

from .models import Item


class CustomUserChoiceField(forms.ModelChoiceField):
    def label_from_instance(self, obj):
         return obj.get_full_name()


class ItemForm(forms.ModelForm):
    user = CustomUserChoiceField(queryset=User.objects.all())

    class Meta:
        model = Item

######################################
## admin.py ##
######################################

from django.contrib import admin

from .models import Item
from .forms import ItemForm


class ItemAdmin(admin.ModelAdmin):
    form = ItemForm


admin.site.register(Item, ItemAdmin)

Source Code Reference

https://github.com/django/django/blob/1.4.5/django/forms/models.py#L948

Related Questions

  1. Django admin - change ForeignKey display text
  2. Django forms: how to dynamically create ModelChoiceField labels
  3. Change Django ModelChoiceField to show users' full names rather than usernames
  4. Django show get_full_name() instead or username in model form
  5. django: customizing display of ModelMultipleChoiceField
  6. django how to display users full name in FilteredSelectMultiple
  7. Django ModelChoiceField drop down box custom population
  8. customize select in django admin
  9. Use method other than unicode in ModelChoiceField Django
like image 199
pankaj28843 Avatar answered Nov 19 '22 09:11

pankaj28843


Django uses unicode(obj) (or the related function, str(obj)) in a number of places. Most notably, to display an object in the Django admin site and as the value inserted into a template when it displays an object.

Please see __unicode__ from https://docs.djangoproject.com/en/dev/ref/models/instances/

You can change __unicode__ method of User class. See below example codes.

from django.db import models
from django.contrib.auth.models import User

def myunicode(self):
    return self.get_full_name()

# Create your models here.
class Item(models.Model):
    User.__unicode__ = myunicode
    user = models.ForeignKey(User)
    name = models.CharField("name", max_length=60)

    def __unicode__(self):
        return self.name
like image 2
Wonil Avatar answered Nov 19 '22 10:11

Wonil