假设我(作为一个人为的例子)有两个模型Dog
和House
,他们拥有所有者的外键。对于此示例,假设每个Owner
最多只能有一个Dog
和一个House
。
class Dog(models.Model):
name = models.CharField(max_length=36)
fk_owner = models.ForeignKey(Owner)
class House(models.Model):
address = models.CharField(max_length=128)
color = models.CharField(max_length=6) #hexcode
fk_owner = models.ForeignKey(Owner)
我从API获取序列化数据。我可以单独为Dog
和House
对象获取它,如下所示:
serializers.py
from rest_framework import serializers
from my_app import Dog
class DogSerializer(serializers.ModelSerializer):
owner = serializers.CharField(source=fk_owner.name, read_only=True)
class Meta:
model = Dog
fields = ('name', 'owner')
#same thing for House
dog_api.py
from my_app.views import DogSerializer
from my_app.models import Dog
from rest_framework import generics
from django.utils.decorators import method_decorator
from rest_framework.decorators import api_view
@method_decorator(api_view(['GET']), name='dispatch')
class DogAPI(generics.ListAPIView):
model=Dog
serializer_class=DogSerializer
queryset = Dog.objects.all()
哪个会给我JSON:[{"name" : "SnoopDogg", "owner" : "Bob Jones"}, etc]
组合两个具有相同Owner
的JSON查询的最佳做法是什么(记住每个Owner
只拥有一个House
和Dog
) ? DRF可以做到,还是我需要编写自己的合并功能?我想生成这个JSON:
[{"name":"SnoopDogg", "owner":"Bob Jones", "house":
{"address":"1 Main St", "color":"FC09A9"}
},
{"name":"Snoopy", "owner":"Charlie Brown", "house":
{"address":"1 Comic Strip", "color":"00FF00"}
},
etc...
]
答案 0 :(得分:1)
首先,如果拥有者只能拥有一只狗和一所房子,那么您应该使用OneToOne
relation代替OneToMany。
class Dog(models.Model):
name = models.CharField(max_length=36)
fk_owner = models.OneToOneField(Owner)
class House(models.Model):
address = models.CharField(max_length=128)
color = models.CharField(max_length=6) #hexcode
fk_owner = models.OneToOneField(Owner)
如果我找到了你,你希望DogAPI
视图也能归还所有者/狗居住的房子。您可以通过在HouseSerializer
中定义SerializerMethodField
和DogSerializer
来实现这一目标:
from rest_framework import serializers
from my_app import Dog, House
class HouseSerializer(serializers.ModelSerializer):
class Meta:
model = House
class DogSerializer(serializers.ModelSerializer):
owner = serializers.CharField(source=fk_owner.name, read_only=True)
house = serializers.SerializerMethodField()
class Meta:
model = Dog
fields = ('name', 'owner', 'house')
def get_house(self, obj):
"""
Return serialized house data
"""
house = obj.fk_owner.house
return HouseSerializer(house).data