django-reversion: revision with json serialized_data fails upon DateField

Hi!

my reversioned model contains a DateField called “date”. Django-reversion used to, and still does, work fine with that model if the serialized_data is xml. With json serialized_data it fails: see exception added below, reproduced in manage.py shell.

I narrowed down the problem to wrong json data: django-reverison produces a revision whith json serialized_data which contains “date”: “2011-05-05 00:00:00”. So if i change that to “date”: “2011-05-05” everything’s back to normal.

/path/to/latest/reversion/models.pyc in get_object_version(self)
    187         if isinstance(data, unicode):
    188             data = data.encode("utf8")
--> 189         return list(serializers.deserialize(self.format, data))[0]
    190 
    191     object_version = property(get_object_version,

/usr/lib/pymodules/python2.7/django/core/serializers/json.pyc in Deserializer(stream_or_string, **options)
     33     else:
     34         stream = stream_or_string
---> 35     for obj in PythonDeserializer(simplejson.load(stream), **options):
     36         yield obj
     37 

/usr/lib/pymodules/python2.7/django/core/serializers/python.pyc in Deserializer(object_list, **options)
    126             # Handle all other fields
    127             else:
--> 128                 data[field.name] = field.to_python(field_value)
    129 
    130         yield base.DeserializedObject(Model(**data), m2m_data)

/usr/lib/pymodules/python2.7/django/db/models/fields/__init__.pyc in to_python(self, value)
    609 
    610         if not ansi_date_re.search(value):
--> 611             raise exceptions.ValidationError(self.error_messages['invalid'])
    612         # Now that we have the date string in YYYY-MM-DD format, check to make

    613         # sure it's a valid date.


ValidationError: [u'Enter a valid date in YYYY-MM-DD format.']

About this issue

  • Original URL
  • State: closed
  • Created 13 years ago
  • Comments: 25 (15 by maintainers)

Most upvoted comments

I’d still strongly suggest finding the bit of your code that’s assigning a string to a datetime field, and fixing the root problem there.

Sure, parts of Django are okay with this, but other parts are not.

On 30 July 2018 at 18:32, Jesús Avellaneda Menchón <notifications@github.com

wrote:

Hi,

I don’t know if this is still a problem with recent versions of Django or Reversion, but I solved this issue for my company overriding the Django’s JSON deserializer.

  1. Create a module fixing the problem in the deserializer:

#!/usr/bin/env python# -- coding: utf-8 -- from django.core.serializers.json import *from django.core.serializers.python import _get_modelfrom django.utils.dateparse import parse_datetimefrom django.db import modelsfrom copy import deepcopy

def _fix_datefield_with_datetime_deserialization(objects): # Si a un DateField se le quiere deserializar un datetime, # se debe eliminar la parte del tiempo para evitar errores # del tipo: DeserializationError: [u"El valor ‘2018-06-04T00:00:00’ # tiene formato de fecha inválido. Debe ser de la forma YYYY-MM-DD."] new_objects = deepcopy(objects) models.get_apps()

for i, d in enumerate(objects):
    model = _get_model(d['model'])

    for field_name, field_value in d['fields'].iteritems():
        # noinspection PyProtectedMember
        field = model._meta.get_field(field_name)

        if field_value and type(field) == models.DateField:
            parsed = parse_datetime(field_value)

            if parsed:
                new_objects[i]['fields'][field_name] = parsed.date().isoformat()

return new_objects

def Deserializer(stream_or_string, **options): “”" Deserialize a stream or string of JSON data. “”" if not isinstance(stream_or_string, (bytes, six.string_types)): stream_or_string = stream_or_string.read() if isinstance(stream_or_string, bytes): stream_or_string = stream_or_string.decode(‘utf-8’) try: objects = json.loads(stream_or_string) objects = _fix_datefield_with_datetime_deserialization(objects)

    for obj in PythonDeserializer(objects, **options):
        yield obj

except GeneratorExit:
    raise
except Exception as e:
    # Map to deserializer error
    raise DeserializationError(e)
  1. Use this serialization module on your settings.py

SERIALIZATION_MODULES = {‘json’: ‘common.json_serializers’}

It might be a bit hacky, but I found it to be the only feasible way for us to get rid of the problem. I hope it helps!

— You are receiving this because you modified the open/close state. Reply to this email directly, view it on GitHub https://github.com/etianen/django-reversion/issues/61#issuecomment-408945988, or mute the thread https://github.com/notifications/unsubscribe-auth/AAJFCHGEty2-SKxkOCPQ42jvHbhc_C_7ks5uL0MRgaJpZM4AC2J5 .