Opened 2 years ago

Closed 2 years ago

#22090 closed Cleanup/optimization (needsinfo)

ModelAdmin list_filter field member values are serialized using __str__ and not __repr__

Reported by: sam@… Owned by: nobody
Component: contrib.admin Version: 1.6
Severity: Normal Keywords: admin, list_filter
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no


When generating the filter URL query parameters corresponding to model members with choice fields and specified in list_filter of ModelAdmin, Django uses the str method of each of the choices to generate the URL query representation of each.

The Django docs specifically note the str as being one which returns an informal human readable representation:

Django should not be assuming that the str value is unambiguous or machine readable. The python standard noted at regarding repr() is that repr should be the function used for outputting a machine representation of the object:

"If at all possible, this should look like a valid Python expression that could be used to recreate an object with the same value (given an appropriate environment)."

The above described inconvenience means that I have to make the str method in the values that I assign to my model members machine readable, which is goes against both Django and Python recommendations and makes my code messier.

Change History (8)

comment:1 Changed 2 years ago by aaugustin

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset
  • Resolution set to needsinfo
  • Status changed from new to closed

I'm not sure to understand your message.

Since you're referring to the __str__ method of models, maybe you're thinking of foreign keys, but in that case Django uses xxx__id__exact=yyy, so there's no __str__ or __repr__ involved.

choices are an iterable of 2-uples where:

  • the first item is an arbitrary object corresponding to the underlying database field
  • the second item a a string describing that object

Both should be unique to avoid ambiguity. Since the second item is guaranteed to be a string, it's natural to use it in the URL. But once again there's no __str__ or __repr__ involved.

Can you provide a sample and that exhibits the problem you're reporting?

comment:2 Changed 2 years ago by anonymous

list_filter is using the str value returned by the first member of the choice tuple (value_object, human_readable_string). i.e. The str representation of the value of the choice. I am arguing that list_filter should use the repr of value_object instead, since it is being used as a serialized representation.

comment:3 Changed 2 years ago by sam@…

The above comment was me, forgot to put my email in

comment:4 Changed 2 years ago by aaugustin

  • Resolution needsinfo deleted
  • Status changed from closed to new

I'm not sure I understand. Looking at a site of mine, list_filter is using the *second* member of the choice tuple.

Bumping back to unreviewed.

comment:5 Changed 2 years ago by sam@…

I haven't found the code responsible, but changing the return value of str to the machine readable representation changed the URL parameter value used when list filtering to the machine readable representation also. I deduce from this that the str of the choice value is used as the query parameter.

comment:6 Changed 2 years ago by aaugustin

I still don't understand what you're talking about. The second member must be a string, not an arbitrary object.

Can you post the definition of your choices?

comment:7 Changed 2 years ago by sam@…

Say that (value, 'human readable choice string') is one of the choice tuples for some field, and value is an instance of my own data-type python class which has an associated models.Field subclass to which values of this type can be assigned. Then Django is using value.__str__() as the URL parameter serialization when the web browser in the admin site filters by that choice.

I am arguing that __str__() is not the right function to call to get a serialisation, because __str__() is said by the official Python documentation to be the 'informal' (human readable) representation, whereas __repr__() is a formal representation which, as long as it makes sense, should be suitable for formal representation (such as serialization) if possible. Django's current behaviour means that my custom field class must be able to parse whatever is returned by value.__str__() in order to correctly filter the admin page.

My complaint is perhaps more of a stylistic point but I think that consistency with Python best-practice is worthwhile. Otherwise, my value.__str__() function can not possibly be made to give an 'informal' representation without breaking the Django admin.

comment:8 Changed 2 years ago by bmispelon

  • Resolution set to needsinfo
  • Status changed from new to closed

I've also tried and failed to reproduce the problem described in this ticket.

Can you provide some code example that demonstrate your issue?


Note: See TracTickets for help on using tickets.
Back to Top