2

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?

Michał Werner
  • 285
  • 4
  • 10

4 Answers4

1

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

Celeo
  • 5,583
  • 8
  • 39
  • 41
  • 3
    I would like to avoid altering __str__, because i use it in other places. Maybe I should force the field renderer (?) to use other function, not __str__. But how? – Michał Werner Nov 25 '14 at 20:01
  • @user2395401 why do you want to avoid _\_str_\_ ? – doniyor Nov 25 '14 at 20:42
  • 1
    Because I'm already using it to display article title in other places. Here, I want to add something more to title, but only here. – Michał Werner Nov 25 '14 at 20:47
  • @moonchild who said you cannot use _\_str_\_ in two places? what do you mean with "other places" – doniyor Nov 25 '14 at 20:57
  • 1
    I mean now my `__str__` returns `self.title` and I use it in several places in frontend to display article title. I could change it to return let's say `self.category + ' | ' + self.title` and that will solve my problem in admin site, but I would have to modify some frontend, so I would like to avoid it, if possible. – Michał Werner Nov 25 '14 at 21:06
  • @moonchild why and what would you have to modify in frontend because of this? this is just object description, in frontend you can retrieve any data from object you want. what is the big deal? – doniyor Nov 25 '14 at 21:09
0

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.

Jerry Stratton
  • 3,287
  • 1
  • 22
  • 30
0

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?

doniyor
  • 36,596
  • 57
  • 175
  • 260
0

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.

jenniwren
  • 341
  • 2
  • 10