Reputation: 6607
I'm serializing a bunch of objects with:
json = serializers.serialize("json", objects, fields=('name', 'country'))
I have not included 'pk' in my fields list, but the produced JSON includes a primary key with each serialized object. I do not want my API to expose primary keys to the general public.
Short of munging the output JSON, what is the correct way to tell serializers.serialze()
to not include the primary key?
Upvotes: 21
Views: 15591
Reputation: 31
I had the same problem, so I created my own Serializer
, inheritance from Serializer from Django.
I'd like only field's data, so I overwrite the method get_dump_object
, and added the PK field.
from django.core.serializers.json import Serializer
class JSONSerializer(Serializer):
def get_dump_object(self, obj):
self._current[obj._meta.pk.name] = obj._get_pk_val()
return self._current
And call:
output = JSONSerializer().serialize(queryset)
Upvotes: 3
Reputation: 434
What Josh did but backwards:
data = json.loads(json_string)
for d in data:
del d['pk']
del d['model']
data = json.dumps(data)
this way you don't have to worry about updating the code when adding more fields in the future.
Upvotes: 13
Reputation: 7
The ugly (but working) way :
data_tmp = data.split('{')
#Gets all the data after fields
response = "[{"+data_tmp[2].replace("}}","}",1)
Upvotes: -1
Reputation: 4634
You may also override JSON serializer as explained here: Override Django Object Serializer to get rid of specified model
from django.core.serializers.json import Serializer, DjangoJSONEncoder
from django.utils import simplejson
import logging
class MySerializer(Serializer):
def end_serialization(self):
cleaned_objects = []
for obj in self.objects:
del obj['pk']
cleaned_objects.append(obj)
simplejson.dump(cleaned_objects, self.stream, cls=DjangoJSONEncoder, **self.options)
Upvotes: 9
Reputation: 1483
Although this is an old question, someone else will probably come up with it on a Google search.
Unfortunately the django serializer offers fairly little customization like what you defined. My solution, if you know you will be using a lot of serialization for your project, was simply to copy django's serialization stuff over to my own project and make some small changes. This isn't ideal, but it does the job. Specifically, to remove the pk's, there is a line in start_object(self, obj):
self.xml.startElement("object", {
"pk" : smart_unicode(obj._get_pk_val()),
"model" : smart_unicode(obj._meta),
})
Removing the "pk" line should fix it. It's a somewhat dirty hack, since if they improve this later on it may require some changes to your views, but for me this was the easiest way around the limitations.
Hope this helps someone.
Upvotes: 3
Reputation: 6607
I ended up working around this by 'manually' achieving what I wanted using the underlying simplejson
serializer:
from django.utils import simplejson
json = simplejson.dumps( [{'name': o.name,
'country': o.country} for o in objects] )
A little more typing, but works.
Upvotes: 18
Reputation: 391872
We don't waste our time trying to "sanitize" the PK's. When we produce a JSON record, the PK is there, and the user can ignore it if they want. They can't do anything with the information, so it's just clutter.
None of our web services interfaces allow anyone to provide a PK back to us. We do POST, PUT and DELETE searches on other fields, but not the PK.
The HTML, however, shows the PK's the URL's all the time. It lets people bookmark the pages.
Upvotes: -3