如何扩展Tastypie API以返回关联对象
嘿,作为刚接触Django和Tastypie的新手,这个需求其实挺常见的,我来一步步教你怎么实现~
实现步骤
1. 先确保Django模型有正确的父子关联
首先你的OU模型得有一个指向自身的外键,用来表示父子层级关系,还要设置related_name方便反向查询子对象:
from django.db import models class OU(models.Model): name = models.CharField(max_length=255) displayname = models.CharField(max_length=255) inherit = models.BooleanField(default=True) # 指向父OU,related_name用来反向获取子OU集合 parent = models.ForeignKey( 'self', on_delete=models.CASCADE, related_name='child_ou', null=True, blank=True ) def __str__(self): return self.name
2. 修改Tastypie的Resource配置
接下来要在你的OUResource里配置关联字段,让API能正确处理子对象的返回,有两种常用方式:
方式一:让主接口直接嵌入子对象完整数据
如果你希望访问/api/v1/ou/33/时,返回结果里直接包含子对象的全部信息,同时保留child_ou_uri的访问能力,可以这么写:
from tastypie.resources import ModelResource from tastypie.fields import ToManyField from .models import OU class OUResource(ModelResource): # 关联子OU,full=True表示返回完整的子对象数据,而不只是URI child_ou = ToManyField('self', 'child_ou', full=True, null=True) class Meta: queryset = OU.objects.all() resource_name = 'ou' fields = ['id', 'name', 'displayname', 'inherit']
这样配置后,访问/api/v1/ou/33/的返回结果里会多一个child_ou字段,里面是所有子对象的完整数据;同时访问/api/v1/ou/33/child_ou/依然能拿到子对象的列表。
方式二:仅通过child_ou_uri返回子对象(默认增强)
如果只是希望child_ou_uri能正确返回子对象数据,不需要在主接口里嵌入,只要正确声明关联字段就行:
class OUResource(ModelResource): # 声明反向关联的子OU字段 child_ou = ToManyField('self', 'child_ou', null=True) class Meta: queryset = OU.objects.all() resource_name = 'ou' fields = ['id', 'name', 'displayname', 'inherit']
这时候访问/api/v1/ou/33/child_ou/就会返回该OU下所有子对象的详细列表,每个子对象包含自身的resource_uri和基本字段。
3. 自定义返回格式(可选)
如果你需要更灵活的输出格式,可以用dehydrate方法手动处理子对象的返回内容,比如只返回子对象的URI列表:
def dehydrate(self, bundle): # 手动生成子OU的URI列表 if bundle.obj.child_ou.exists(): bundle.data['child_ou'] = [ self.get_resource_uri(child) for child in bundle.obj.child_ou.all() ] else: bundle.data['child_ou'] = [] return bundle
注意点
如果你的模型里的反向关联名称不是child_ou,记得要对应修改Resource里ToManyField的第二个参数哦!
内容的提问来源于stack exchange,提问作者Spoonbendr
相关产品推荐
相关产品推荐

