Django 在公共外键上合并两个序列化查询集的正确方法
假设我有(作为一个人为的例子)两个模型Django 在公共外键上合并两个序列化查询集的正确方法,django,django-rest-framework,Django,Django Rest Framework,假设我有(作为一个人为的例子)两个模型狗和房子,它们的主人有外键。在本例中,假设每个所有者最多可以有一只狗和一所房子 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) colo
狗
和房子
,它们的主人有外键。在本例中,假设每个所有者最多可以有一只狗
和一所房子
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获取序列化数据。我可以分别为狗
和房子
对象获取它,如下所示:
序列化程序.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”:“snoopdog”,“owner”:“Bob Jones”},等等]
问题是:
组合两个拥有相同所有者的JSON查询的最佳实践方法是什么(记住每个所有者只拥有一个房子和狗)?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...
]
首先,如果一个主人只能养一只狗和一所房子,那么你应该用一只狗而不是一只猫
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
视图也能返回主人/狗居住的房子。您可以通过在DogSerializer
中定义HouseSerializer
和SerializerMethodField
来实现这一点:
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