19

I'm trying to use the ValuesQuerySet feature in Django to limit the number of fields returned from query to only those I need. I would like to serialize this data set a JSON object However, Django keeps throwing an error. Below I've included my code and the error I receive:

objectList = ConventionCard.objects.values('fileName','id').filter(ownerUser = user)
data = serializers.serialize('json', objectList)
return HttpResponse(data, mimetype='application/javascript')

The Error:

Exception Type:     AttributeError
Exception Value:    'dict' object has no attribute '_meta'
Exception Location:     C:\Python27\lib\site-packages\django\core\serializers\base.py in serialize, line 41

Thanks !

12
  • Why are you using values()? That makes dict objects which can't easily be serialized. Commented Jul 6, 2011 at 18:27
  • 3
    I don't want my entire object. I just want two fields. Values seems to be the way to do this. Is there a better way? Commented Jul 6, 2011 at 18:28
  • 1
    @S.Lott Values does exactly what it's suppose to do: it returns a subset of the fields. What doesn't work is the serialization of the resulting object. Commented Jul 6, 2011 at 18:39
  • 8
    @S.Lott "I'm trying to use the ValuesQuerySet feature in Django to limit the number of fields returned from query to only those I need." It was clear in the question. Commented Nov 4, 2011 at 15:00
  • 1
    @S.Lott True. I'm reminded of a poster once that said, Instead of saying "This doesn't make sense!" you should say "I don't understand." We all should work towards understanding. Commented Nov 11, 2011 at 15:55

4 Answers 4

35

Cast the ValuesQuerySet to a list first:

query_set = ConventionCard.objects.values('fileName','id').filter(ownerUser = user)

list(query_set)

Removing the values call as suggested by ars causes the manager to pull all columns from the table, instead of only the two you need.

Sign up to request clarification or add additional context in comments.

2 Comments

Brilliant answer. Works beautifully.
It does not work in my environment (Python 3.4, Django 1.8.3).
18

Try subsetting the fields in your values list through the serialize method using a QuerySet instead:

from django.core import serializers
objectQuerySet = ConventionCard.objects.filter(ownerUser = user)
data = serializers.serialize('json', objectQuerySet, fields=('fileName','id'))

2 Comments

Not ideal because the query is pulling all column data out when it only needs the two fields.
when i was trying this thing, i noticed that, serializers.serialize fields option, did not select the column/fields of related models. Anybody faced the same?
14

I continued to get a dict object has no attribute _meta error when using the list() method above. However I found this snippet that does the trick

def ValuesQuerySetToDict(vqs):
    return [item for item in vqs]

# Usage
data = MyModel.objects.values('id','title','...','...')
data_dict = ValuesQuerySetToDict(data)
data_json = simplejson.dumps(data_dict)

2 Comments

Module simplejson was removed in Django 1.5. The alternative is to simply import json and then use json.dumps(data_dict) and the answer is as expected.
This needs to be higher because the serializer has two flaws. 1. rest_framework also has serialzer, so you have to do from django.core import serializers as emily, and the second is the serializer doesnt' work on a queryset like this: statement_line.objects.select_related('ae').values('ae__opp_own', 'cur','ae_id').annotate(tots=Sum('amt'))
1

Just to add a few details I've found:

When I tried @ars answer specifying the fields, like:

s_logs = serializers.serialize("json", logs, fields=('user', 'action', 'time'))

I get this:

[{"pk": 520, "model": "audit.auditlog", "fields": {"user": 3, "action": "create", "time":"2012-12-16T12:13:45.540"}}, ... ]

Which was not a simple serialization of the values as I wanted it.

So I tried the solution proposed by @Aaron, converting the valuesqueryset to a list, which didn't work the first time because the default encoder cannot deal with floats or datetime objects.

So I used @Aaron solution but using the JSON encoder that is used by django's serializer (DjangoJSONEncoder) by passing it as a kwarg to simplejson.dumps(), like this:

s_logs = list(logs.values('user', 'ip', 'object_name', 'object_type', 'action', 'time'))

return HttpResponse(simplejson.dumps( s_logs, cls=DjangoJSONEncoder ), mimetype='application/javascript')

1 Comment

If you are using simplejson > 2.1, take a look at this issue: github.com/simplejson/simplejson/issues/37 Given that issue, one might have to subclass simplejson.JSONEncoder instead of json.JSONEncoder

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.