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 !
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.
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'))
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)
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')
Related
class PreUpdateDeleteAPIView(APIView):
serializer_class = PreEditSerializer
queryset = Reserve.objects.all()
def post(self, request):
code = request.data()
"""''.join(code)"""
data = {
reverse('update-delete', args = [code] ,request=request)
}
return Response(data)
hello. i have an problem for converting querydict to string. what should i do now?
i have tried json.dump and several answers in SOF. but i didnt get my answer yet!
request.data is a property that returns a QueryDict, so you work with:
code = request.data
It however makes no sense to specify args=[code], since code is a dictionary-like structure.
Likely you need some value that corresponds to some key from the request.data, so something like:
code = request.data['code']
I'm building a DRF api endpoint that should render some json data from my database. In my view, the name of the model to query to render the data is not fixed, it depends on what query does the user perform.
So i have this:
collection = 'MY_MODEL'
queryset = collection.objects.filter(**filters)
But this will give the following error:
'str' object has no attribute 'objects'
This will work instead: queryset = MY_MODEL.objects.filter(**filters)
Is there any way to get around this?
Django actually has a method to do this:
from django.utils.module_loading import import_string
ModelClass = import_string('yourapp.models.YOUR_MODEL')
queryset = ModelClass.objects.filter(**filters)
Note that you have to provide the full path of your model.
The docs: https://docs.djangoproject.com/en/3.1/ref/utils/#django.utils.module_loading.import_string
If you only have a few models you need to support however I would actually advise to just use a dictionary that you maintain yourself:
MODEL_MAPPING = {
"model_a": MyModelAClass,
"model_b": MyModelBClass,
}
user_input = "model_b"
ModelClass = MODEL_MAPPING.get(user_input)
if ModelClass is not None:
queryset = ModelClass.objects.filter(**filters)
When I use like below
data , error = schema.load( json_data )
data object contains only values not keys but json_data is a valid dict.
and if I just use
MyModel = _mymodel(**json_data)
it works. But if I use below inside of my schema
#post_load
def create_model(self, data):
return MyModel(**data)
I get error
AttributeError: 'MyModel' object has no attribute 'get'
Anyone has any idea? Why "data" contains only value and does not return dictionary like the examples stated?
Thanks
According to documentation here there are two methods similar to each others.
load(data, many=None, partial=None)
Deserialize a data structure to an object defined by this Schema’s fields and make_object().
Another is
loads(json_data, many=None, *args, **kwargs)
Same as load(), except it takes a JSON string as input.
So you need to use loads() instead of load() if you have json data.
I have the following ListView
import json
class CountryListView(ListView):
model = Country
def render_to_response(self, context, **response_kwargs):
return json.dumps(self.get_queryset().values_list('code', flat=True))
But I get following error:
[u'ae', u'ag', u'ai', u'al', u'am',
u'ao', u'ar', u'at', u'au', u'aw',
u'az', u'ba', u'bb', u'bd', u'be', u'bg',
u'bh', u'bl', u'bm', u'bn', '...(remaining elements truncated)...']
is not JSON serializable
Any ideas ?
It's worth noting that the QuerySet.values_list() method doesn't actually return a list, but an object of type django.db.models.query.ValuesListQuerySet, in order to maintain Django's goal of lazy evaluation, i.e. the DB query required to generate the 'list' isn't actually performed until the object is evaluated.
Somewhat irritatingly, though, this object has a custom __repr__ method which makes it look like a list when printed out, so it's not always obvious that the object isn't really a list.
The exception in the question is caused by the fact that custom objects cannot be serialized in JSON, so you'll have to convert it to a list first, with...
my_list = list(self.get_queryset().values_list('code', flat=True))
...then you can convert it to JSON with...
json_data = json.dumps(my_list)
You'll also have to place the resulting JSON data in an HttpResponse object, which, apparently, should have a Content-Type of application/json, with...
response = HttpResponse(json_data, content_type='application/json')
...which you can then return from your function.
class CountryListView(ListView):
model = Country
def render_to_response(self, context, **response_kwargs):
return HttpResponse(json.dumps(list(self.get_queryset().values_list('code', flat=True))),mimetype="application/json")
fixed the problem
also mimetype is important.
Below I'm trying to get a query make is a json object, so that in my template using jQuery I can loop over it.
My View
from django.core import serializers
objectQuerySet = Recipient.objects.filter(incentiveid=incentive).values("mobile", "countryid")
data = serializers.serialize("json", objectQuerySet)
return render_to_response('smssend.html', context_instance=RequestContext(request))
I'm getting the following error.
Non-model object (<type 'dict'>) encountered during serialization
Request Method:
why?
#values() "returns dictionaries when used as an iterable" - https://docs.djangoproject.com/en/dev/ref/models/querysets/#django.db.models.query.QuerySet.values
I think you need python's json#dumps(dict) here