#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?