我一直致力于在Django中开发一些RESTful服务,以便与Flash和Android应用程序一起使用.
开发服务接口非常简单,但我遇到了序列化具有外键和多对多关系的对象的问题.
我有这样的模型:
class Artifact( models.Model ): name = models.CharField( max_length = 255 ) year_of_origin = models.IntegerField( max_length = 4, blank = True, null = True ) object_type = models.ForeignKey( ObjectType, blank = True, null = True ) individual = models.ForeignKey( Individual, blank = True, null = True ) notes = models.TextField( blank = True, null = True )
然后我将使用这样的模型执行查询select_related()
,以确保遵循外键关系:
artifact = Artifact.objects.select_related().get(pk=pk)
一旦我拥有了该对象,我将其序列化,并将其传递回我的视图:
serializers.serialize( "json", [ artifact ] )
这就是我得到的,请注意外键(object_type和individual)只是其相关对象的id.
[ { pk: 1 model: "artifacts.artifact" fields: { year_of_origin: 2010 name: "Dummy Title" notes: "" object_type: 1 individual: 1 } } ]
这很好,但我在使用时希望的select_related()
是它会自动使用相关对象填充外键字段,而不仅仅是对象的id.
我最近转换为Django,但是花了相当多的时间用CakePHP开发.
我真正喜欢Cake ORM的是它默认会遵循关系并创建嵌套对象,并且能够在调用查询时解除绑定关系.
这使得以一种不需要任何干预的方式抽象服务非常容易.
我看到Django默认不这样做,但有没有办法自动序列化一个对象及其所有相关的对象?任何提示或阅读将非常感激.
虽然不是出于RESTful目的,但我有类似的要求.在我的案例中,我能够通过使用"完整"序列化模块来实现我所需要的Django Full Serializers
.这是wadofstuff的一部分,并根据新的BSD许可证分发.
Wadofstuff使这很容易.例如,在您的情况下,您需要执行以下操作:
首先,安装wadofstuff.
其次,将以下设置添加到您的settings.py
文件中:
SERIALIZATION_MODULES = { 'json': 'wadofstuff.django.serializers.json' }
第三,对用于序列化的代码稍作修改:
artifact = Artifact.objects.select_related().get(pk=pk) serializers.serialize( "json", [ artifact ], indent = 4, relations = ('object_type', 'individual',))
关键变化是relations
关键字参数.唯一(次要)陷阱是使用形成关系的字段的名称而不是相关模型的名称.
警告
从文档:
在序列化模型时,Wad of Stuff序列化器与Django序列化器100%兼容.在反序列化数据流时,
Deserializer
该类当前仅适用于标准Django序列化程序返回的序列化数据.
(重点补充)
希望这可以帮助.
更新:实际上Manoj的解决方案有点过时,Wad of Stuff的序列化器已经有一段时间没有更新了,当我尝试时,它似乎不再支持Django 1.6了.
但是,请看一下Django的官方文档.它确实提供了一些使用内置自然键的方法.似乎django的内置序列化器在支持使用ImageField作为自然键的一部分方面存在一些问题.但这可以很容易地由你自己修复.