views:

398

answers:

3

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?

A: 

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.

S.Lott
Many companies assume that no information is contained within sequential primary keys. If you have your access controls locked down, nothing to worry about, right?Wrong. At the very least, revealing sequential identifiers provides a great way for competitors to keep track of your growth. There is a sizeable industry simply based on finding sequential ID's and selling growth estimates.
Josh Reich
You may approach you problem by using UUID instead of sequential ID's so exposing them to public won't provide any information for competitors.
Mike Korobov
+3  A: 

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.

Josh Reich
that's fine solution if you just want to dump some data to json and don't care about FK's.
Mike Korobov
@Josh It's a lot more coding if you have 28 methods using 5 models in an API.
orokusaki
A: 

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.

philipk