allow DateTimeFields to accept strings as input · Issue #2656 · encode/django-rest-framework (original) (raw)
I found an interesting "bug" with Django Rest Framework along with how Django's DateTimeField works. Given the following TestCase:
class ReadOnlyDateTimeModel(models.Model):
date = models.DateTimeField()
def save(self, *args, **kwargs):
self.date = '2015-02-03 00:00:00'
return super(ReadOnlyDateTimeModel, self).save(*args, **kwargs)
class ReadOnlyDateTimeSerializer(serializers.ModelSerializer):
date = serializers.DateTimeField(read_only=True)
class Meta:
model = ReadOnlyDateTimeModel
class ReadOnlyDateTimeView(generics.ListCreateAPIView):
queryset = ReadOnlyDateTimeModel.objects.all()
serializer_class = ReadOnlyDateTimeSerializer
class TestReadOnlyFieldSerializer(TestCase):
def setUp(self):
self.view = ReadOnlyDateTimeView.as_view()
def test_model_save_works(self):
obj = ReadOnlyDateTimeModel.objects.create()
assert obj.date == '2015-02-03 00:00:00'
def test_post_root_view(self):
"""
POST requests to ListCreateAPIView should create a new object.
"""
data = {'price': 1}
request = factory.post('/', data, format='json')
response = self.view(request).render()
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
I see this error:
tests/test_generics.py:544: in test_post_root_view
response = self.view(request).render()
/usr/local/lib/python2.7/site-packages/django/views/decorators/csrf.py:57: in wrapped_view
return view_func(*args, **kwargs)
/usr/local/lib/python2.7/site-packages/django/views/generic/base.py:69: in view
return self.dispatch(request, *args, **kwargs)
rest_framework/views.py:452: in dispatch
response = self.handle_exception(exc)
rest_framework/views.py:449: in dispatch
response = handler(request, *args, **kwargs)
rest_framework/generics.py:244: in post
return self.create(request, *args, **kwargs)
rest_framework/mixins.py:21: in create
headers = self.get_success_headers(serializer.data)
rest_framework/serializers.py:466: in data
ret = super(Serializer, self).data
rest_framework/serializers.py:213: in data
self._data = self.to_representation(self.instance)
rest_framework/serializers.py:435: in to_representation
ret[field.field_name] = field.to_representation(attribute)
rest_framework/fields.py:879: in to_representation
value = value.isoformat()
E AttributeError: 'unicode' object has no attribute 'isoformat'
It seems like Django will accept a formatted string as input, however DRF tries to format the field as a datetime rather than a string, causing the above failure case. If I change self.date = '2015-02-03 00:00:00'
to self.date = datetime.datetime.now()
, it all works as expected.