Skip to content

Commit e4c246e

Browse files
Stefan Majoorstefanmajoor
authored andcommitted
Fix for running after on a filter with a relation that is none
1 parent e7c422a commit e4c246e

File tree

2 files changed

+40
-1
lines changed

2 files changed

+40
-1
lines changed

binder/views.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1561,6 +1561,21 @@ def _after_expr(self, request, after_id, include_annotations):
15611561
whens = []
15621562

15631563
for field in ordering:
1564+
# Fields are generally strings, except in some edge case, where it is an OrderBy expression.
1565+
# In thase case, we need to change it back to starting (sigh) for compatability reasons
1566+
1567+
if type(field) is not str:
1568+
_field = field
1569+
1570+
field = field.expression.name
1571+
1572+
if _field.descending:
1573+
field = f'-{field}'
1574+
if _field.nulls_first:
1575+
field = f'{field}__nulls_first'
1576+
if _field.nulls_last:
1577+
field = f'{field}__nulls_last'
1578+
15641579
# First we have to split of a leading '-' as indicating reverse
15651580
reverse = field.startswith('-')
15661581
if reverse:
@@ -1583,7 +1598,7 @@ def _after_expr(self, request, after_id, include_annotations):
15831598
# Then we determine what the value is for the obj we need to be after
15841599
value = obj
15851600
for attr in field.split('__'):
1586-
value = getattr(value, attr)
1601+
value = getattr(value, attr, None)
15871602
if isinstance(value, models.Model):
15881603
value = value.pk
15891604

tests/test_after.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,3 +88,27 @@ def test_ordered_with_null_reversed(self):
8888
self.assertEqual(self.get('-birth_date'), 'edbacf')
8989
self.assertEqual(self.get('-birth_date', after='c'), 'f')
9090
self.assertEqual(self.get('-birth_date', after='b'), 'acf')
91+
92+
def test_after_with_nullable_foreign_key(self):
93+
"""
94+
There was a bug that if you filtered on a nullable relation, and the relation was not set for the after,
95+
then it would crash. Here we test that this doesn't happen again
96+
"""
97+
98+
first_animal = Animal.objects.all()[0]
99+
first_animal.zoo = None
100+
first_animal.save()
101+
102+
self.get('-zoo.name', after=self.mapping[first_animal.pk])
103+
104+
def test_after_with_nullable_foreign_key_and_nulls_first(self):
105+
"""
106+
There was a bug that if you filtered on a nullable relation, and the relation was not set for the after,
107+
then it would crash. Here we test that this doesn't happen again
108+
"""
109+
110+
first_animal = Animal.objects.all()[0]
111+
first_animal.zoo = None
112+
first_animal.save()
113+
114+
self.get('-zoo.name__nulls_first', after=self.mapping[first_animal.pk])

0 commit comments

Comments
 (0)