diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py
index ed2bc06..68e5016 100644
a
|
b
|
class Query(object):
|
693 | 693 | Returns True if the join was promoted by this call. |
694 | 694 | """ |
695 | 695 | if ((unconditional or self.alias_map[alias][NULLABLE]) and |
696 | | self.alias_map[alias][JOIN_TYPE] != self.LOUTER): |
| 696 | self.alias_map[alias][JOIN_TYPE] == self.INNER): |
697 | 697 | data = list(self.alias_map[alias]) |
698 | 698 | data[JOIN_TYPE] = self.LOUTER |
699 | 699 | self.alias_map[alias] = tuple(data) |
diff --git a/tests/modeltests/aggregation/tests.py b/tests/modeltests/aggregation/tests.py
index a35dbb3..722808b 100644
a
|
b
|
class BaseAggregateTestCase(TestCase):
|
565 | 565 | (Decimal('82.8'), 1), |
566 | 566 | ] |
567 | 567 | ) |
| 568 | |
| 569 | def test_ticket17424(self): |
| 570 | """ |
| 571 | Check that doing exclude() on a foreign model after annotate() |
| 572 | doesn't crash. |
| 573 | """ |
| 574 | from django.db.models.sql.constants import JOIN_TYPE |
| 575 | all_books = list(Book.objects.values_list('pk', flat=True)) |
| 576 | |
| 577 | annotated_books = Book.objects.annotate(one=Count("id")) |
| 578 | |
| 579 | # The value doesn't matter, we just need any negative |
| 580 | # constraint on a related model that's a noop. |
| 581 | excluded_books = annotated_books.exclude(publisher__name="__UNLIKELY_VALUE__") |
| 582 | |
| 583 | # Try to generate query tree |
| 584 | unicode(excluded_books.query) |
| 585 | |
| 586 | self.assertQuerysetEqual(excluded_books, all_books, lambda x: x.pk, ordered=True) |
| 587 | |
| 588 | # Check internal state |
| 589 | self.assertIsNone(annotated_books.query.alias_map["aggregation_book"][JOIN_TYPE]) |
| 590 | self.assertIsNone(excluded_books.query.alias_map["aggregation_book"][JOIN_TYPE]) |