From e1f13f15512ece2d8ea8c7bf9f704ce4286c2ffa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fl=C3=A1vio=20Juvenal?= Date: Thu, 12 Apr 2018 15:06:43 -0300 Subject: [PATCH] Fixed #29320 -- Added an exception when an annotation alias matches a ForeignKey attname. --- django/db/models/query.py | 6 +++++- tests/aggregation_regress/tests.py | 5 +++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/django/db/models/query.py b/django/db/models/query.py index 71ebf660c7..2db6690c44 100644 --- a/django/db/models/query.py +++ b/django/db/models/query.py @@ -7,6 +7,7 @@ import operator import warnings from collections import OrderedDict, namedtuple from functools import lru_cache +from itertools import chain from django.conf import settings from django.core import exceptions @@ -981,7 +982,10 @@ class QuerySet: clone = self._chain() names = self._fields if names is None: - names = {f.name for f in self.model._meta.get_fields()} + names = set(chain.from_iterable( + (field.name, field.attname) if hasattr(field, 'attname') else (field.name,) + for field in self.model._meta.get_fields() + )) for alias, annotation in annotations.items(): if alias in names: diff --git a/tests/aggregation_regress/tests.py b/tests/aggregation_regress/tests.py index 9c8bac0d21..7f03d66bab 100644 --- a/tests/aggregation_regress/tests.py +++ b/tests/aggregation_regress/tests.py @@ -769,6 +769,11 @@ class AggregationTests(TestCase): with self.assertRaisesMessage(ValueError, msg): Author.objects.annotate(friends=Count('friends')) + def test_fk_attname_conflict(self): + msg = "The annotation 'contact_id' conflicts with a field on the model." + with self.assertRaisesMessage(ValueError, msg): + Book.objects.annotate(contact_id=F('publisher_id')) + def test_values_queryset_non_conflict(self): # Regression for #14707 -- If you're using a values query set, some potential conflicts are avoided.