在 Django 中序列化外键对象 [英] Serializing Foreign Key objects in Django

查看:61
本文介绍了在 Django 中序列化外键对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直致力于在 Django 中开发一些 RESTful 服务,以便与 Flash 和 Android 应用程序一起使用.

开发服务接口非常简单,但我在序列化具有外键和多对多关系的对象时遇到了问题.

我有一个这样的模型:

class Artifact(models.Model):名称 = 模型.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 )个人=models.ForeignKey(个人,空白=真,空=真)笔记 = 模型.TextField(空白 = 真,空 = 真)

然后我会像这样使用 select_related() 对这个模型执行查询,以确保遵循外键关系:

artifact = Artifact.objects.select_related().get(pk=pk)

获得对象后,我将其序列化,并将其传递回我的视图:

serializers.serialize( "json", [ artifact ] )

这是我得到的,注意外键(object_type 和 individual)只是它们相关对象的 id.

<预><代码>[{PK:1模型:artifacts.artifact"字段:{year_of_origin: 2010名称:虚拟标题"注释:"对象类型:1个人:1}}]

这很棒,但我在使用 select_related() 时希望它会自动使用相关对象填充外键字段,而不仅仅是对象的 id.

我最近转换为 Django,但花了相当多的时间使用 CakePHP 进行开发.

我真正喜欢 Cake ORM 的地方在于,它默认会遵循关系并创建嵌套对象,并且能够在您调用查询时解除关系的绑定.

这使得以一种不需要任何个案干预的方式对服务进行抽象变得非常容易.

我看到 Django 默认不这样做,但是有没有办法自动序列化一个对象及其所有相关对象?任何提示或阅读将不胜感激.

解决方案

我也有类似的需求,但不是出于 RESTful 目的.我能够通过使用完整"序列化模块来实现我所需要的,在我的情况下 <代码>Django 完整序列化程序.这是 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,关系 = ('object_type', 'individual',))

关键变化是 relations 关键字参数.唯一的(次要)问题是使用形成关系的字段的名称,而不是相关模型的名称.

警告

来自文档:

<块引用>

在序列化模型时,Wad of Stuff 序列化器与 Django 序列化器 100% 兼容.在反序列化数据流时,Deserializer 类目前仅适用于标准 Django 序列化器返回的序列化数据.

(强调)

希望这会有所帮助.

I have been working on developing some RESTful Services in Django to be used with both Flash and Android apps.

Developing the services interface has been quite simple, but I have been running into an issue with serializing objects that have foreign key and many to many relationships.

I have a model like this:

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 )

Then I would perform a query on this model like this, using select_related(), to be sure that foreign key relationships are followed:

artifact = Artifact.objects.select_related().get(pk=pk)

Once I have the object, I serialize it, and pass that back to my view:

serializers.serialize( "json", [ artifact ] )

This is what I get back, note that the foreign keys (object_type and individual) are just the id's to their related objects.

[
      {
            pk: 1
            model: "artifacts.artifact"
            fields: {
                year_of_origin: 2010
                name: "Dummy Title"
                notes: ""
                object_type: 1
                individual: 1
            }
      }
]

This is great, but what I was hoping for when using select_related() was that it would automatically populate the foreign key fields with the related object, not just the object's id.

I am recent convert to Django, but put in a fair amount of time developing with CakePHP.

What I really like about the Cake ORM was that it would follow the relationships and create nested objects by default, with the ability to unbind the relationships when you were calling your query.

This made it very easy to abstract the services in a way that did not require any intervention on a case by case basis.

I see that Django does not do this by default, but is there a way to automatically serialize an object and all of it's related objects? Any tips or reading would be much appreciated.

解决方案

I had a similar requirement although not for RESTful purposes. I was able to achieve what I needed by using a "full" serializing module, in my case Django Full Serializers. This is part of wadofstuff and is distributed under the new BSD license.

Wadofstuff makes this quite easy. For e.g. in your case you'd need to do the following:

First, install wadofstuff.

Second, add the following setting to your settings.py file:

SERIALIZATION_MODULES = {
    'json': 'wadofstuff.django.serializers.json'
}

Third, make a slight change to the code used for serialization:

artifact = Artifact.objects.select_related().get(pk=pk)
serializers.serialize( "json", [ artifact ], indent = 4, 
    relations = ('object_type', 'individual',))

The key change is the relations keyword parameter. The only (minor) gotcha is to use the name of the fields forming the relation not the names of the related models.

Caveat

From the documentation:

The Wad of Stuff serializers are 100% compatible with the Django serializers when serializing a model. When deserializing a data stream the the Deserializer class currently only works with serialized data returned by the standard Django serializers.

(Emphasis added)

Hope this helps.

这篇关于在 Django 中序列化外键对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆