mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-08-04 20:40:14 +03:00
Merge b54c76b9fd
into 5250700659
This commit is contained in:
commit
a3423d3d45
23
#.gitignore#
Normal file
23
#.gitignore#
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
*.pyc
|
||||||
|
*.db
|
||||||
|
*~
|
||||||
|
.*
|
||||||
|
|
||||||
|
html/
|
||||||
|
htmlcov/
|
||||||
|
coverage/
|
||||||
|
build/
|
||||||
|
dist/
|
||||||
|
*.egg-info/
|
||||||
|
MANIFEST
|
||||||
|
|
||||||
|
bin/
|
||||||
|
include/
|
||||||
|
lib/
|
||||||
|
local/
|
||||||
|
|
||||||
|
*.iml
|
||||||
|
atlassian-ide-plugin.xml
|
||||||
|
|
||||||
|
!.gitignore
|
||||||
|
!.travis.yml
|
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -16,5 +16,8 @@ include/
|
||||||
lib/
|
lib/
|
||||||
local/
|
local/
|
||||||
|
|
||||||
|
*.iml
|
||||||
|
atlassian-ide-plugin.xml
|
||||||
|
|
||||||
!.gitignore
|
!.gitignore
|
||||||
!.travis.yml
|
!.travis.yml
|
||||||
|
|
|
@ -70,6 +70,13 @@ class FilterableItem(BaseFilterableItem):
|
||||||
decimal = models.DecimalField(max_digits=4, decimal_places=2)
|
decimal = models.DecimalField(max_digits=4, decimal_places=2)
|
||||||
date = models.DateField()
|
date = models.DateField()
|
||||||
|
|
||||||
|
#Model of test for #1338
|
||||||
|
|
||||||
|
|
||||||
|
class FilterableISO8601Item(BaseFilterableItem):
|
||||||
|
decimal = models.DecimalField(max_digits=4, decimal_places=2)
|
||||||
|
date = models.DateTimeField()
|
||||||
|
|
||||||
|
|
||||||
# Model for regression test for #285
|
# Model for regression test for #285
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ from django.utils.dateparse import parse_date
|
||||||
from rest_framework import generics, serializers, status, filters
|
from rest_framework import generics, serializers, status, filters
|
||||||
from rest_framework.compat import django_filters
|
from rest_framework.compat import django_filters
|
||||||
from rest_framework.test import APIRequestFactory
|
from rest_framework.test import APIRequestFactory
|
||||||
from .models import BaseFilterableItem, FilterableItem, BasicModel
|
from .models import BaseFilterableItem, FilterableItem, FilterableISO8601Item, BasicModel
|
||||||
from .utils import temporary_setting
|
from .utils import temporary_setting
|
||||||
|
|
||||||
factory = APIRequestFactory()
|
factory = APIRequestFactory()
|
||||||
|
@ -760,3 +760,94 @@ class SensitiveOrderingFilterTests(TestCase):
|
||||||
{'id': 3, username_field: 'userC'}, # PassA
|
{'id': 3, username_field: 'userC'}, # PassA
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class Iso8601DateFilter(TestCase):
|
||||||
|
"""
|
||||||
|
Test cases around the filtering of Iso8601 formated dates
|
||||||
|
"""
|
||||||
|
|
||||||
|
def _serialize_object(self, obj):
|
||||||
|
return {'id': obj.id, 'text': obj.text, 'decimal': obj.decimal, 'date': obj.date}
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
"""
|
||||||
|
Set up 2 filterable ISO8601 format dates
|
||||||
|
"""
|
||||||
|
base_data = ('a', Decimal('0.25'), datetime.date(2012, 10, 8))
|
||||||
|
for i in range(2):
|
||||||
|
text = chr(i + ord(base_data[0])) * 3 # Produces string 'aaa', 'bbb', etc.decimal = base_data[1] + i
|
||||||
|
date = base_data[2] - datetime.timedelta(days=i * 2)
|
||||||
|
decimal = base_data[1] + i
|
||||||
|
FilterableItem(text=text, decimal=decimal, date=date.isoformat()).save()
|
||||||
|
|
||||||
|
self.objects = FilterableItem.objects
|
||||||
|
self.data = [
|
||||||
|
self._serialize_object(obj)
|
||||||
|
for obj in self.objects.all()
|
||||||
|
]
|
||||||
|
|
||||||
|
def test_filter_isoformat_date(self):
|
||||||
|
view = FilterFieldsRootView.as_view()
|
||||||
|
# Tests that the date filter works with ISO8601 format.
|
||||||
|
search_date = datetime.date(2012, 9, 22)
|
||||||
|
request = factory.get('/', {'date': '%s' % search_date.isoformat()}) # search_date str: '2012-09-22'
|
||||||
|
response = view(request).render()
|
||||||
|
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||||
|
expected_data = [f for f in self.data if f['date'] == search_date]
|
||||||
|
self.assertEqual(response.data, expected_data)
|
||||||
|
|
||||||
|
def test_filter_isoformat_datetime_against_date_fails(self):
|
||||||
|
view = FilterFieldsRootView.as_view()
|
||||||
|
# Tests that the date filter fails with an ISO8601 datetime format.
|
||||||
|
search_date = datetime.datetime(2012, 8, 12, 12, 00, 00)
|
||||||
|
request = factory.get('/', {'date': '%s' % search_date.isoformat()}) # search_date str: '2012-09-22T12:00:00'
|
||||||
|
response = view(request).render()
|
||||||
|
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||||
|
expected_data = [f for f in self.data if f['date'] == search_date]
|
||||||
|
# This should be [] because date != datetime
|
||||||
|
self.assertEqual(response.data, [])
|
||||||
|
self.assertEqual(response.data, expected_data)
|
||||||
|
|
||||||
|
|
||||||
|
class Iso8601DateTimeFilter(TestCase):
|
||||||
|
"""
|
||||||
|
Test cases around the filtering of Iso8601 formated datetimes
|
||||||
|
"""
|
||||||
|
|
||||||
|
def _serialize_object(self, obj):
|
||||||
|
return {'id': obj.id, 'text': obj.text, 'decimal': obj.decimal, 'date': obj.date.isoformat()}
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
"""
|
||||||
|
Set up 2 filterable ISO8601 format datetimes
|
||||||
|
"""
|
||||||
|
base_data = ('a', Decimal('0.25'), datetime.datetime(2012, 10, 8, 12, 00, 00))
|
||||||
|
for i in range(2):
|
||||||
|
text = chr(i + ord(base_data[0])) * 3 # Produces string 'aaa', 'bbb', etc.
|
||||||
|
decimal = base_data[1] + i
|
||||||
|
date = base_data[2] - datetime.timedelta(days=i * 2)
|
||||||
|
FilterableISO8601Item(text=text, decimal=decimal, date=date.isoformat()).save()
|
||||||
|
|
||||||
|
self.objects = FilterableISO8601Item.objects
|
||||||
|
self.data = [
|
||||||
|
self._serialize_object(obj)
|
||||||
|
for obj in self.objects.all()
|
||||||
|
]
|
||||||
|
|
||||||
|
def test_filter_isoformat_datetime(self):
|
||||||
|
view = FilterFieldsRootView.as_view()
|
||||||
|
# Tests that the date filter works with ISO8601 format.
|
||||||
|
search_date = datetime.datetime(2012, 10, 8, 12, 00, 00)
|
||||||
|
request = factory.get('/', {'date': '%s' % search_date.isoformat()}) # search_date str: '2012-09-22'
|
||||||
|
response = view(request).render()
|
||||||
|
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||||
|
expected_data = [f for f in self.data if f['date'] == search_date.isoformat()]
|
||||||
|
# This shows that the you cannot filter via an isoformatted datetime
|
||||||
|
self.assertNotEqual(response.data, expected_data)
|
||||||
|
# This shows that the issues is not Django filters itself but how the filters are built via iexact
|
||||||
|
should_not_find_something = FilterableISO8601Item.objects.filter(date__iexact=search_date.isoformat())
|
||||||
|
should_find_something = FilterableISO8601Item.objects.filter(date=search_date.isoformat())
|
||||||
|
self.assertEqual(should_not_find_something.count(), 0)
|
||||||
|
# The issue is that dates are being filtered via an iexact filter which does date comparision
|
||||||
|
self.assertNotEqual(should_find_something.count(), should_not_find_something.count())
|
||||||
|
|
Loading…
Reference in New Issue
Block a user