43

Customizing a Django Admin panel, I'm using raw_id_fields to select a ForeignKey from a Model which has thousands of elements, because the default select-box drop-down is inconvenient with so many elements.

It works but it shows the id as can be seen on this image: enter image description here

Is there any way to show the name or other field instead of the id? Or, is there any better way to accomplish this than using raw_id_fields?

This is my code in models.py:

class Structure(MPTTModel):
    name = models.CharField(max_length=200, unique=True, verbose_name = _('name'))
    parent = TreeForeignKey('self', null=True, blank=True, related_name='children', verbose_name = _('parent'))

    def __unicode__(self):
        return u"%s" % (self.name)

In admin.py:

class StructureAdmin(tree_editor.TreeEditor):
    search_fields = ('name',)
    raw_id_fields = ('parent',)
Community
  • 1
  • 1
A.Vila
  • 1,456
  • 4
  • 21
  • 32
  • http://stackoverflow.com/questions/2809122/how-to-show-raw-id-value-of-a-manytomany-relation-in-the-django-admin – catherine Mar 20 '13 at 03:08
  • 1
    if you just want get rid of huge data loading and editing is not needed, use `readonly_fields = ('parent', )`. – Ali Dec 03 '13 at 11:21

4 Answers4

43

From Django 2.0 you can use autocomplete_fields. It will work just like ajax select2.

In admin.py

class StructureAdmin(tree_editor.TreeEditor):
    search_fields = ('name',)
    autocomplete_fields = ('parent',)

Reference: https://docs.djangoproject.com/en/2.1/ref/contrib/admin/#django.contrib.admin.ModelAdmin.autocomplete_fields

hashlash
  • 897
  • 8
  • 19
anjaneyulubatta505
  • 10,713
  • 1
  • 52
  • 62
  • 8
    Wow, I have been developing in Django professionally for five years, and somehow never came across `autocomplete_fields`. Fantastic feature. – Greg Kaleka Jan 20 '20 at 23:42
  • Yes this must be the correct answer. Very cool feature and built-in as well. – BjornW Oct 23 '20 at 12:12
8

I've also researched this and I don't think it's possible. I think the best you can do is display the unicode of the field next to the raw id field: http://djangosnippets.org/snippets/2108/

Alternatively, you can display the unicode and a link to the value's corresponding admin change page: http://djangosnippets.org/snippets/2217/

nofinator
  • 2,906
  • 21
  • 25
  • Thanks for your answer. I've tried the last snippet, but it only shows the unicode and the link when I save the Structure and I open it again. Do you know how can I show the same but when I choose the raw_id? – A.Vila Apr 02 '13 at 18:55
  • @A.Vila I'm having the same behavior, did you have any other alternatives ? – elsadek Jun 25 '14 at 06:59
5

It seems this plugin: https://github.com/lincolnloop/django-dynamic-raw-id

does what you want:

(copied from the doc):

Usage

To start using django-dynamic-raw-id in your application all you need to do is implement DynamicRawIDMixin in your ModelAdmin class and add the desired fields to a list of dynamic_raw_id_fields:

from dynamic_raw_id.admin import DynamicRawIDMixin

class UserProfileAdmin(DynamicRawIDMixin, admin.ModelAdmin):
    dynamic_raw_id_fields = ('user',)

You can use dynamic_raw_id widgets in a Admin filter as well:

from dynamic_raw_id.admin import DynamicRawIDMixin
from dynamic_raw_id.filters import DynamicRawIDFilter

class UserProfileAdmin(DynamicRawIDMixin, admin.ModelAdmin):
    list_filter = (
        ('dynamic_raw_id_fk', DynamicRawIDFilter),
    )
Ersain
  • 1,466
  • 1
  • 9
  • 20
Saze
  • 289
  • 3
  • 8
  • 1
    @coup Regarding your [suggested edit](https://stackoverflow.com/review/suggested-edits/24030698) for *"Change salmonella to dynamic_raw_id"*, it's well worth adding *why*, suggested edit reviewers are not necessarily going to investigate why you are making such a change, maybe next time mention something along the lines of *"salmonella renamed to dynamic_raw_id"* as per documentation. As you can see from the link, your edit did get 1 rejection vote for conflicting with what the user wrote, likely because the editor couldn't understand *why* you made the change. – Nick is tired Sep 13 '19 at 09:15
2

For the representation of an object use __unicode__

class Person(models.Model):
    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)

    def __unicode__(self):
        return u'%s %s' % (self.first_name, self.last_name)

In Python 3 use

def __str__(self):
Glyn Jackson
  • 8,228
  • 4
  • 29
  • 52