2009-10-23 33 views
18

我一个序列化对象一堆用:删除pk场

json = serializers.serialize("json", objects, fields=('name', 'country')) 

我没有将“PK”在我的字段列表,但所产生的JSON包括与每一个序列化的主键目的。我不希望我的API向主要公众公开主键。

传输输出JSON的缺点是什么,告知serializers.serialze()不包含主键的正确方法是什么?

+0

@Josh帝国?有一张票据谈到它@ http://code.djangoproject.com/ticket/4656 – orokusaki 2010-02-11 06:42:03

+0

我最终手动调用了simplejson – 2010-03-05 18:09:46

回答

16

我结束了解决此工作由“手动”实现自己梦想的使用基础simplejson串行:

from django.utils import simplejson 
json = simplejson.dumps([{'name': o.name, 
          'country': o.country} for o in objects]) 

多一点打字,但作品。

+0

这是很好的解决方案,如果你只是想把一些数据转储到json而不关心FK的话。 – 2009-10-23 21:28:16

+0

@Josh如果您有28种方法在API中使用5个模型,那么编码就会更多。 – orokusaki 2010-02-11 06:18:35

+0

我用过这个。但是,在多个视图中使用它时很麻烦。最好使用Django的序列化器。最后一个答案有一个相关问题的链接,它解释了如何从它生成的对象中删除pk和模型字段。 – Dmitry 2012-10-15 22:56:15

0

我们不会浪费时间试图“消毒”PK的。当我们产生JSON记录时,PK就在那里,如果用户愿意,用户可以忽略它。他们不能对信息做任何事情,所以它只是混乱。

我们的Web服务接口都不允许任何人向我们提供PK。我们在其他领域进行POST,PUT和DELETE搜索,但不是PK。

但是,HTML显示PK的URL始终。它可以让人们为书签添加书签。

+7

许多公司都假设顺序主键中没有信息。如果你的访问控制被锁定了,没有什么可担心的,对吧? 错误。至少,揭示连续的标识符为竞争对手提供了一个很好的方式来跟踪你的发展。有一个相当大的行业只是基于发现序列ID和销售增长估计。 – 2009-10-23 21:00:52

+0

您可能会通过使用UUID而不是顺序ID来解决您的问题,因此将其公开给公众将不会为竞争对手提供任何信息。 – 2009-10-23 21:27:32

+0

同时考虑包含pk&model时发送给每个用户的额外文本。这是可以非常清楚地保存的带宽(特别是发送给移动用户时)。 – shaond 2012-01-04 20:44:14

3

虽然这是一个老问题,但其他人可能会在Google搜索中提出这个问题。

不幸的是,django序列化程序提供的定制相当少,就像您定义的那样。我的解决方案,如果你知道你会为你的项目使用很多序列化,只是简单地将django的序列化的东西复制到我自己的项目中,并做一些小的改变。这并不理想,但是它完成了这项工作。具体来说,除去PK的,有在start_object行(个体经营,OBJ):

self.xml.startElement("object", { 
     "pk" : smart_unicode(obj._get_pk_val()), 
     "model" : smart_unicode(obj._meta), 
    }) 

取出 “PK” 行应该修复它。这是一个有点肮脏的黑客,因为如果他们后来改进这可能需要对您的意见进行一些更改,但对我而言,这是解决限制的最简单方法。

希望这可以帮助别人。

7

您也可以覆盖JSON序列如下解释: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) 
+0

谢谢!这个问题的答案帮助了很多! – Dmitry 2012-10-15 22:55:00

0

丑陋的(但工作)的方式:

data_tmp = data.split('{') 
#Gets all the data after fields 
response = "[{"+data_tmp[2].replace("}}","}",1) 
8

约什做了什么,但后退:

data = json.loads(json_string) 

for d in data: 
    del d['pk'] 
    del d['model'] 

data = json.dumps(data) 

这样,您就不必担心在添加更多字段时更新代码未来。

1

我有同样的问题,所以我创建了我自己的Serializer,继承自Django的Serializer。 我只想要字段的数据,所以我覆盖方法get_dump_object,并添加了PK字段。

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 

而且拨打:

output = JSONSerializer().serialize(queryset) 
那你最终会做这一个