How to modify Django admin ManyToManyField text?

811 views Asked by At

I have "Articles" and "Modules" apps. Inside "Modules" app there is model which have to display articles and they're linked by ManyToManyField in "Modules".

My question is how to modify text value in select field in Django admin? As default it displays names of articles, but i want also some information from Article model here. Is there a simple way to do that?

4

There are 4 answers

0
doniyor On

your question is vague, but i just assume, you have Article Model which has manytomany field with e.g. Something Model

class Something(models.Model):
  name = models.CharField(max_length=10)
  #...
  def __unicode__(self):
    return u"{} whatever text you want".format(self.name)

class Article(models.Model):
  title = models.CharField(max_length=120)
  something = models.ManyToMany(Something)

  def __unicode__(self):
    return u"{}".format(self.title)

in admin, you will see <object_name> whatever text you want for each object in multiple-select-box, is this what you want?

6
Celeo On

Depending on your Python version, you'll either want to override the models' __str__ fields (Python 3), or the models' __unicode__ fields (Python 2) to change how their appear in the admin.

Reference in the Django docs

0
Jerry Stratton On

The Django Admin select menus use the unicode value of the model instance to populate things like menus. Whatever your __unicode__ method returns should be what is in the select menu.

0
jenniwren On

If you are wanting to do this for an admin field, you can use formfield_for_manytomany. In skeleton form it could look like this:

def formfield_for_manytomany(self, db_field, request=None, **kwargs):
    field = super().formfield_for_manytomany(db_field, request, **kwargs)
    if db_field.name in ['the_field_you_want']:

        # This line answers the question.
        field.label_from_instance = lambda obj: "{}".format(obj.what_you_want_to_see)

        # The lines below included so folks know you can
        # also modify queryset and widget in this method
        field.widget = forms.CheckboxSelectMultiple() # checkboxes
        field.queryset = field.queryset.filter(some_field = something)

    return field #important

This came from this answer which achieves the same goal but uses a Form class instead of formfield_for_manytomany.