Skip to content

Commit

Permalink
Use a nullable DateTime model field to test OrderingFilter's handling…
Browse files Browse the repository at this point in the history
… of nulls
  • Loading branch information
earshinov committed May 24, 2020
1 parent ee0e6ba commit 20a6a66
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 72 deletions.
6 changes: 4 additions & 2 deletions tests/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ def formfield(self, **kwargs):

class User(models.Model):
username = models.CharField(_('username'), max_length=255)
first_name = SubCharField(max_length=100, null=True, blank=True)
last_name = SubSubCharField(max_length=100, null=True, blank=True)
first_name = SubCharField(max_length=100)
last_name = SubSubCharField(max_length=100)

status = models.IntegerField(choices=STATUS_CHOICES, default=0)

Expand All @@ -51,6 +51,8 @@ class User(models.Model):

favorite_books = models.ManyToManyField('Book', related_name='lovers')

last_login = models.DateTimeField(null=True)

def __str__(self):
return self.username

Expand Down
151 changes: 81 additions & 70 deletions tests/test_filtering.py
Original file line number Diff line number Diff line change
Expand Up @@ -1872,12 +1872,15 @@ def test_filtering(self):
class OrderingFilterTests(TestCase):

def setUp(self):
User.objects.create(username='alex', first_name='Alex', last_name='Allan', status=1)
User.objects.create(username='jacob', first_name='Jacob', last_name='Johnson', status=2)
User.objects.create(username='aaron', first_name='Aaron', last_name='Barrett', status=2)
User.objects.create(username='carl', first_name=None, last_name='Jung', status=0)
tz = timezone.utc
User.objects.create(username='alex', status=1, last_login=datetime.datetime(2020, 1, 1, tzinfo=tz))
User.objects.create(username='jacob', status=2, last_login=datetime.datetime(2020, 2, 1, tzinfo=tz))
User.objects.create(username='aaron', status=2, last_login=datetime.datetime(2020, 3, 1, tzinfo=tz))
User.objects.create(username='carl', status=0)

def test_ordering(self):
tz = timezone.utc

class F(FilterSet):
o = OrderingFilter(
fields=('username', )
Expand All @@ -1893,6 +1896,8 @@ class Meta:
self.assertEqual(list(names), ['aaron', 'alex', 'carl', 'jacob'])

def test_ordering_with_select_widget(self):
tz = timezone.utc

class F(FilterSet):
o = OrderingFilter(
widget=forms.Select,
Expand All @@ -1909,125 +1914,131 @@ class Meta:
self.assertEqual(list(names), ['aaron', 'alex', 'carl', 'jacob'])

def test_ordering_with_null(self):
tz = timezone.utc

class F(FilterSet):
o = OrderingFilter(
fields=('first_name', 'last_name')
fields=('last_login',)
)

class Meta:
model = User
fields = ['first_name', 'last_name']
fields = ['last_login']

qs = User.objects.all()
f = F({'o': 'first_name,last_name'}, queryset=qs)
names = f.qs.values_list('first_name', 'last_name')
self.assertEqual(list(names), [
(None, 'Jung'),
('Aaron', 'Barrett'),
('Alex', 'Allan'),
('Jacob', 'Johnson'),
f = F({'o': 'last_login'}, queryset=qs)
results = f.qs.values_list('username', 'last_login')
self.assertEqual(list(results), [
('carl', None),
('alex', datetime.datetime(2020, 1, 1, tzinfo=tz)),
('jacob', datetime.datetime(2020, 2, 1, tzinfo=tz)),
('aaron', datetime.datetime(2020, 3, 1, tzinfo=tz)),
])

f = F({'o': '-first_name,-last_name'}, queryset=qs)
names = f.qs.values_list('first_name', 'last_name')
self.assertEqual(list(names), [
('Jacob', 'Johnson'),
('Alex', 'Allan'),
('Aaron', 'Barrett'),
(None, 'Jung'),
f = F({'o': '-last_login'}, queryset=qs)
results = f.qs.values_list('username', 'last_login')
self.assertEqual(list(results), [
('aaron', datetime.datetime(2020, 3, 1, tzinfo=tz)),
('jacob', datetime.datetime(2020, 2, 1, tzinfo=tz)),
('alex', datetime.datetime(2020, 1, 1, tzinfo=tz)),
('carl', None),
])

def test_ordering_with_params_and_null(self):
tz = timezone.utc

class F(FilterSet):
o = OrderingFilter(
params=('first_name', 'last_name')
params=('last_login',)
)

class Meta:
model = User
fields = ['first_name', 'last_name']
fields = ['last_login']

qs = User.objects.all()
f = F({'o': 'first_name,last_name'}, queryset=qs)
names = f.qs.values_list('first_name', 'last_name')
self.assertEqual(list(names), [
(None, 'Jung'),
('Aaron', 'Barrett'),
('Alex', 'Allan'),
('Jacob', 'Johnson'),
f = F({'o': 'last_login'}, queryset=qs)
results = f.qs.values_list('username', 'last_login')
self.assertEqual(list(results), [
('carl', None),
('alex', datetime.datetime(2020, 1, 1, tzinfo=tz)),
('jacob', datetime.datetime(2020, 2, 1, tzinfo=tz)),
('aaron', datetime.datetime(2020, 3, 1, tzinfo=tz)),
])

f = F({'o': '-first_name,-last_name'}, queryset=qs)
names = f.qs.values_list('first_name', 'last_name')
self.assertEqual(list(names), [
('Jacob', 'Johnson'),
('Alex', 'Allan'),
('Aaron', 'Barrett'),
(None, 'Jung'),
f = F({'o': '-last_login'}, queryset=qs)
results = f.qs.values_list('username', 'last_login')
self.assertEqual(list(results), [
('aaron', datetime.datetime(2020, 3, 1, tzinfo=tz)),
('jacob', datetime.datetime(2020, 2, 1, tzinfo=tz)),
('alex', datetime.datetime(2020, 1, 1, tzinfo=tz)),
('carl', None),
])

def test_ordering_with_params_and_nulls_last(self):
tz = timezone.utc

class F(FilterSet):
o = OrderingFilter(
params={
'first_name': {'expr': expressions.F('first_name').asc(nulls_last=True)},
'last_name': {'expr': expressions.F('last_name').asc(nulls_last=True)}
'last_login': {'expr': expressions.F('last_login').asc(nulls_last=True)},
}
)

class Meta:
model = User
fields = ['first_name', 'last_name']
fields = ['last_login']

qs = User.objects.all()
f = F({'o': 'first_name,last_name'}, queryset=qs)
names = f.qs.values_list('first_name', 'last_name')
self.assertEqual(list(names), [
('Aaron', 'Barrett'),
('Alex', 'Allan'),
('Jacob', 'Johnson'),
(None, 'Jung'),
f = F({'o': 'last_login'}, queryset=qs)
results = f.qs.values_list('username', 'last_login')
self.assertEqual(list(results), [
('alex', datetime.datetime(2020, 1, 1, tzinfo=tz)),
('jacob', datetime.datetime(2020, 2, 1, tzinfo=tz)),
('aaron', datetime.datetime(2020, 3, 1, tzinfo=tz)),
('carl', None),
])

f = F({'o': '-first_name,-last_name'}, queryset=qs)
names = f.qs.values_list('first_name', 'last_name')
self.assertEqual(list(names), [
(None, 'Jung'),
('Jacob', 'Johnson'),
('Alex', 'Allan'),
('Aaron', 'Barrett'),
f = F({'o': '-last_login'}, queryset=qs)
results = f.qs.values_list('username', 'last_login')
self.assertEqual(list(results), [
('carl', None),
('aaron', datetime.datetime(2020, 3, 1, tzinfo=tz)),
('jacob', datetime.datetime(2020, 2, 1, tzinfo=tz)),
('alex', datetime.datetime(2020, 1, 1, tzinfo=tz)),
])

def test_ordering_with_params_and_desc_nulls_last(self):
tz = timezone.utc

class F(FilterSet):
o = OrderingFilter(
params={
'first_name': {'expr': expressions.F('first_name').desc(nulls_last=True)},
'last_name': {'expr': expressions.F('last_name').desc(nulls_last=True)}
'last_login': {'expr': expressions.F('last_login').desc(nulls_last=True)},
}
)

class Meta:
model = User
fields = ['first_name', 'last_name']
fields = ['last_login']

qs = User.objects.all()
f = F({'o': 'first_name,last_name'}, queryset=qs)
names = f.qs.values_list('first_name', 'last_name')
self.assertEqual(list(names), [
('Jacob', 'Johnson'),
('Alex', 'Allan'),
('Aaron', 'Barrett'),
(None, 'Jung'),
f = F({'o': 'last_login'}, queryset=qs)
results = f.qs.values_list('username', 'last_login')
self.assertEqual(list(results), [
('aaron', datetime.datetime(2020, 3, 1, tzinfo=tz)),
('jacob', datetime.datetime(2020, 2, 1, tzinfo=tz)),
('alex', datetime.datetime(2020, 1, 1, tzinfo=tz)),
('carl', None),
])

f = F({'o': '-first_name,-last_name'}, queryset=qs)
names = f.qs.values_list('first_name', 'last_name')
self.assertEqual(list(names), [
(None, 'Jung'),
('Aaron', 'Barrett'),
('Alex', 'Allan'),
('Jacob', 'Johnson'),
f = F({'o': '-last_login'}, queryset=qs)
results = f.qs.values_list('username', 'last_login')
self.assertEqual(list(results), [
('carl', None),
('alex', datetime.datetime(2020, 1, 1, tzinfo=tz)),
('jacob', datetime.datetime(2020, 2, 1, tzinfo=tz)),
('aaron', datetime.datetime(2020, 3, 1, tzinfo=tz)),
])


Expand Down

0 comments on commit 20a6a66

Please sign in to comment.