#24936 closed Bug (needsinfo)
AttributeError appears when one tries to use defer/only for a field in a model that has the reverse relationship explicitly removed
Reported by: | lukawoj | Owned by: | nobody |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | dev |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
While investigating #24612 I discovered that if one tries to use defer/only for a field in a model that has the reverse relationship explicitly removed, AttributeError appears. Code changed since #24612 was logged and now it throws following error:
AttributeError: 'ManyToOneRel' object has no attribute 'attname'
Models:
# models.py from django.db import models from django.contrib.auth.models import User class Message(models.Model): content = models.CharField(max_length=10) class MessageParticipant(models.Model): msg = models.ForeignKey(Message, related_name='participants') user = models.ForeignKey(User, related_name='+')
Query to use:
list(Message.objects.all().only('participants__user__username'))
Error:
Traceback (most recent call last): File "C:/dev/django_con/django_sprint_2015/django_sprint/django/tests\defer\tests.py", line 279, in test_defer_only list(Message.objects.all().only('participants__user__username')) File "C:\dev\django_con\django_sprint_2015\django_sprint\django\django\db\models\query.py", line 258, in __iter__ self._fetch_all() File "C:\dev\django_con\django_sprint_2015\django_sprint\django\django\db\models\query.py", line 1063, in _fetch_all self._result_cache = list(self.iterator()) File "C:\dev\django_con\django_sprint_2015\django_sprint\django\django\db\models\query.py", line 52, in __iter__ results = compiler.execute_sql() File "C:\dev\django_con\django_sprint_2015\django_sprint\django\django\db\models\sql\compiler.py", line 835, in execute_sql sql, params = self.as_sql() File "C:\dev\django_con\django_sprint_2015\django_sprint\django\django\db\models\sql\compiler.py", line 384, in as_sql extra_select, order_by, group_by = self.pre_sql_setup() File "C:\dev\django_con\django_sprint_2015\django_sprint\django\django\db\models\sql\compiler.py", line 48, in pre_sql_setup self.setup_query() File "C:\dev\django_con\django_sprint_2015\django_sprint\django\django\db\models\sql\compiler.py", line 39, in setup_query self.select, self.klass_info, self.annotation_col_map = self.get_select() File "C:\dev\django_con\django_sprint_2015\django_sprint\django\django\db\models\sql\compiler.py", line 196, in get_select for c in self.get_default_columns(): File "C:\dev\django_con\django_sprint_2015\django_sprint\django\django\db\models\sql\compiler.py", line 504, in get_default_columns only_load = self.deferred_to_columns() File "C:\dev\django_con\django_sprint_2015\django_sprint\django\django\db\models\sql\compiler.py", line 772, in deferred_to_columns self.query.deferred_to_data(columns, self.query.get_loaded_field_names_cb) File "C:\dev\django_con\django_sprint_2015\django_sprint\django\django\db\models\sql\query.py", line 684, in deferred_to_data callback(target, model, values) File "C:\dev\django_con\django_sprint_2015\django_sprint\django\django\db\models\sql\query.py", line 1804, in get_loaded_field_names_cb target[model] = {f.attname for f in fields} File "C:\dev\django_con\django_sprint_2015\django_sprint\django\django\db\models\sql\query.py", line 1804, in <setcomp> target[model] = {f.attname for f in fields} AttributeError: 'ManyToOneRel' object has no attribute 'attname'
Note:
See TracTickets
for help on using tickets.
Is
only()
even supposed to work withManyToOneRel
?What are you expecting
Message.objects.only('participants__user__username')
to return since m2m relationships are not implicitly prefetched?What does the following yields?