Python – In Django Admin, I want to change how foreign keys are displayed in a Many-Many Relationship admin widget

djangodjango-admindjango-widgetpython

I have a ManyToMany relationship:

class Book:
  title = models.CharField(...)
  isbn = models.CharField(...)

  def unicode(self):
    return self.title

  def ISBN(self):
    return self.isbn

class Author:
  name = models.CharField(...)
  books = models.ManyToManyField(Book...)

In the admin interface for Author I get a multiple select list that uses the unicode display for books. I want to change the list in two ways:

1) Only for the admin interface I want to display the ISBN number, everywhere else I just print out a "Book" object I want the title displayed.

2) How could I use a better widget than MultipleSelectList for the ManyToMany. How could I specify to use a CheckBoxSelectList instead?

Best Answer

To display the ISBN you could make a custom field like this:


class BooksField(forms.ModelMultipleChoiceField):
    def label_from_instance(self, obj):
        return obj.isbn

There's a CheckboxSelectMultiple for the ManyToManyField but it doesn't display correctly on the admin, so you could also write some css to fix that.

You need to create a form for the model, and use that in your admin class:


class AuthorForm(forms.ModelForm):
    books = BooksField(Book.objects.all(), widget=forms.CheckboxSelectMultiple)

    class Meta:
        model = Author

    class Media:
        css = {
            'all': ('booksfield.css',)
        }

class AuthorAdmin(admin.ModelAdmin):
    form = AuthorForm
Related Topic