django.db.models.query.QuerySet.__repr__ should not have side-effects
|Reported by:||Owned by:||nobody|
|Component:||Database layer (models, ORM)||Version:||1.4|
|Severity:||Normal||Keywords:||QuerySet, repr, side-effect|
|Has patch:||yes||Needs documentation:||no|
|Needs tests:||no||Patch needs improvement:||no|
In trying to track down some timeouts and strange queries in our apps we saw some strange queries being run by django. We were querying for a single record with a FOR UPDATE, getting an error, then django would run the same query 3 times but with a limit of 21 and then fetch all of the records, each time.
Eventually I tracked this down to our error-handling middleware calling repr() on a QuerySet, which then queried the database.
__repr__ is supposed to be a string-representation of an object in its current state and should not gave side-effects like making database queries, especially in the case where the query uses FOR UPDATE or similar logic.
I suggest changing
django.db.models.query.QuerySet.__repr__ to only touch the cached records and not use the local iterator, which can and will query the DB, potentially causing issues like this.