Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django Serializer AttributeError: 'unicode' object has no attribute 'isoformat'

I'm trying to serialize an instance of a (customized) Django User Model like so:

In models.py:

Class Employee(User):
    company = models.ForeignKey('Company')
    additionalField1
    additionalField2
    etc....

In the Employee model above, in addition to the attributes inherited from the User model, I use the following model field types: CharField(), NullBooleanField(), IntegerField(), DateField(), DecimalField()

The code in question:

employee = Employee()
(snip large amounts of code that sets various attributes for employee)
serializers.serialize("json", [employee, ])

(I have WadOfStuff's Django full serializer plugin installed, btw, in case that matters -- but in this case I believe it should be defaulting to the standard Django serializer because I'm not using any of the full serializer's functionality in this case)

The employee __dict__ (with a few key fields anonymized) right before serialization is attempted:

{'status': u'Act', 'last_name': u'Doe', 'payFrequency': u'Mo', '_state':
 <django.db.models.base.ModelState object at 0x15be890>, 'sex': u'M', 'user_ptr_id': 
None, 'is_staff': False, 'isRegistered': False, 'hireDate': u'2012-08-01', 'id': None, 
'date_joined': datetime.datetime(2012, 10, 25, 2, 39, 22, 793015, tzinfo=<UTC>), 
'city': u'San Francisco', 'first_name': u'John', 'zip': u'94114', u'employmentType': 
u'FT', 'company_id': 4, 'compType': u'S', 'is_superuser': False, 'state': u'CA', 
'last_login': datetime.datetime(2012, 10, 25, 2, 39, 22, 792983, tzinfo=<UTC>), 
'email': '', 'username': 'tu7wwhyskewcpheyoq4lk3i3l', 'address2': '', 'is_active': 
True, 'phone': '', 'address': u'111 Cherry Lane', 'password': 
'pbkdf2_sha256$10000$OAlOtfQClAV2$OC9oCe/9P5hjc4nWd1ZW6cY117PmW1pny8J41axr6mM=', 
'salary': u'10833.00', 'standardHours': None, 'dob': u'1980-04-01', 'socialSecurity': 
u'555555555', 'middleInitial': '', 'payRate': None}

Partial traceback:

File "/usr/lib/python2.6/site-packages/django/core/serializers/__init__.py", l                                                                                                                     ine 98, in serialize
s.serialize(queryset, **options)
File "/usr/lib/python2.6/site-packages/wadofstuff/django/serializers/base.py",                                                                                                                      line 52, in serialize
self.handle_field(obj, field)
File "/usr/lib/python2.6/site-packages/wadofstuff/django/serializers/python.py                                                                                                                     ", line 71, in handle_field
self._fields[field.name] = field.value_to_string(obj)
File "/usr/lib/python2.6/site-packages/django/db/models/fields/__init__.py", l                                                                                                                     ine 722, in value_to_string
return '' if val is None else val.isoformat()
AttributeError: 'unicode' object has no attribute 'isoformat'

Any ideas what might be causing the error or how I can get serialization working in this case? Presumably there is some kind of attribute that the Serializer doesn't like -- how can I figure out which one?

like image 393
CQP Avatar asked Oct 25 '12 03:10

CQP


2 Answers

isoformat is a method that's typically used on a datetime.datetime or datetime.date object, it looks like it's attempting to do this on a string.

My suspicion is that either "hireDate" or "dob," should be an object date/datetime object but isn't. Based on the traceback you could try setting those attributes to be None and see if you encounter the error again. Alternatively, you should try seeing if Django will save the model to the database with the data you have. If not that's probably what's causing your problem, in which case the data is being put into the Employee object with the wrong type.

like image 114
Aea Avatar answered Nov 08 '22 07:11

Aea


When upgrading from DRF2.X to DRF3.X this issue can suddenly appear, as happened to me. The reason is stated in the DRF 3.0 announcement as a backward incompatible change:

Date and Time objects are now coerced to strings by default in the serializer output. Previously they were returned as Date, Time and DateTime objects, and later coerced to strings by the renderer.

The way to fix it is to tell it to behave as it did before (have the serializer return the object representation and let the renderer convert it to string). The 2 ways to do so are also indicated in the announcement page.

  1. globally for the application add this to your settings.py under the REST_FRAMEWORK sections (along with other preferences that you probably already have):

    # Return native `Date` and `Time` objects in `serializer.data`
    'DATETIME_FORMAT': None,
    'DATE_FORMAT': None,
    'TIME_FORMAT': None
    
  2. individually for fields of choice in the serializer def:

    created = serializers.DateTimeField(format=None)

like image 2
Legato Avatar answered Nov 08 '22 07:11

Legato