Saturday, February 5, 2011

'unicode' object has no attribute '_meta'

It appears I have run across another annoying problem for which there is a lot of contradicting information. I'm working on a Django project and I ran into this error: 'unicode' object has no attribute '_meta'. What is really important is the context in which I received the error. There are a lot of different possible culprits and an even larger number of possible fixes.

The context within I was receiving this error was in a view function that was "supposed" to be returning a list of strings in json. If you have any experience with returning Django queryset results in json you probably immediately think of doing something like this:

#Not what you want!
from django.core import serializers 
from django.http import HttpResponse
from myproject.myapp.models import MyModel

def get_my_strings(request):
    some_models = MyModel.objects.filter(user=request.user)
    my_strings = []
    for s in my_strings:
        my_strings.append(some_models.some_string)
    #error will be thrown
    my_strings = serializers.serialize('json', my_strings) 
    return HttpResponse(my_strings, mimetype='application/json')

This is wrong.

What you actually want is to use the simplejson.dumps function to serialize your data.  Here is the correct form:

#Import simplejson instead
from django.utils import simplejson 
from django.http import HttpResponse
from myproject.myapp.models import MyModel

def get_my_strings(request):
    some_models = MyModel.objects.filter(user=request.user)
    my_strings = []
    for s in my_strings:
        my_strings.append(some_models.some_string)
    #Corrected!
    my_strings = simplejson.dumps(my_strings, indent=4) 
    return HttpResponse(my_strings, mimetype='application/json'

2 comments:

  1. Saved my life.

    Any idea why this is necessary? Is it because the django serializer doesn't know how to deal with unicode strings?

    ReplyDelete
  2. Eric - I'm not entirely sure why. I would be willing to bet it has something to do with the serializer expecting a Model object to be passed to it, and not a more common Python object like a string. My experience has been when in doubt, just use simplejson to serialize it yourself.

    ReplyDelete