Python 正确使用Django';s ORM和Django Rest框架来序列化嵌套关系的查询集?
构建queryset的正确方法是什么?我可以将它传递到Django Rest Framework序列化程序中,以获得相关嵌套对象的数据/json结果 例如,我有两种型号:Python 正确使用Django';s ORM和Django Rest框架来序列化嵌套关系的查询集?,python,json,django,django-rest-framework,django-orm,Python,Json,Django,Django Rest Framework,Django Orm,构建queryset的正确方法是什么?我可以将它传递到Django Rest Framework序列化程序中,以获得相关嵌套对象的数据/json结果 例如,我有两种型号: class Topping(models.Model): name = models.CharField(max_length=50) class Pizza(models.Model): name = models.CharField(max_length=50) toppings = models
class Topping(models.Model):
name = models.CharField(max_length=50)
class Pizza(models.Model):
name = models.CharField(max_length=50)
toppings = models.ManyToManyField(Topping)
和我的序列化程序:
class ToppingSerializer(serializers.Serializer):
name = serializers.CharField(required=True, max_length=50)
class PizzaSerializer(serializers.Serializer):
name = serializers.CharField(required=True, max_length=50)
toppings = ToppingSerializer(many=True, required=False)
然后,如何创建并传入查询集以获得类似以下内容的结果:
[
{
"name": "Hawaiian",
"toppings": [
{"name": "Pinapple"},
{"name": "Canadian Bacon"},
{"name": "Cheese"}
]
},
{
"name": "Pepperoni Pizza",
"toppings": [
{"name": "Pepperoni"},
{"name": "Cheese"}
]
},
{
"name": "Jamaican",
"toppings": [
{"name": "Chicken"},
{"name": "Jerk"},
{"name": "Cheese"}
]
}
]
请注意: Django Rest框架有一个很好的使用ModelSerializer的功能,但是我需要这个功能,而不使用ModelSerializer,因为我的序列化需求将在DB模型表示之外变得非常定制
其他信息: “”的Django Rest框架文档很有帮助,但我仍然不确定如何将正确的queryset传递给这样的“嵌套对象序列化程序”
如何创建“嵌套”查询集?首先,您需要使用而不是
序列化程序,并提供元属性。如果使用默认字段配置,则不需要显式提供序列化程序字段
class ToppingSerializer(serializers. ModelSerializer):
class Meta:
model = Topping
fields = ('name',)
class PizzaSerializer(serializers. ModelSerializer):
class Meta:
model = Pizza
fields = ('name', 'toppings')
之后,只需使用并向其提供序列化程序
class PizzaListApiView(ListAPIView):
queryset = Pizza.objects.all()
serializer_class = PizzaSerializer
更新
如何创建“嵌套”查询集
嵌套表示模型中带有ForeignKey
或ManyToManyField
,就像您的Pizza
模型一样。例如,如果要显式地执行查询集()的操作,可以在查询集上执行
为了完整性,以及其他找到本页的人,下面是实现类似结果的两种不同方法
感谢Sardorbek最初回答这个问题
观点:
class PizzaList(APIView):
"""
View for the Serializer not using ModelSerializer
"""
def get(self, request, format=None):
pizzas = Pizza.objects.all().prefetch_related('toppings')
serializer = PizzaSerializer(pizzas, many=True)
return Response(serializer.data)
class PiePizzaList(APIView):
"""
View for the Serializer useing ModelSerializer
"""
def get(self, request, format=None):
pizzas = Pizza.objects.all()
serializer = PiePizzaSerializer(pizzas, many=True)
return Response(serializer.data)
序列化程序1(不带ModelSerializer):
或序列化程序2(带ModelSerializer):
谢谢你的回复,萨多贝克。如我问题的最后几行所述,如果可能的话,我想在使用ModelSerializer
创建自定义查询集之外实现此功能。@aero我认为使用ModelSerializer
并扩展它没有问题,ModelSerializer
是Serializer
的子类。这意味着你可以用序列化程序你可以用ModelSerializer
做的一切,甚至更好的是,它可以为你访问数据库做所有的工作。你的更新完全回答了我的问题。谢谢你的努力,萨多贝克!
class PizzaList(APIView):
"""
View for the Serializer not using ModelSerializer
"""
def get(self, request, format=None):
pizzas = Pizza.objects.all().prefetch_related('toppings')
serializer = PizzaSerializer(pizzas, many=True)
return Response(serializer.data)
class PiePizzaList(APIView):
"""
View for the Serializer useing ModelSerializer
"""
def get(self, request, format=None):
pizzas = Pizza.objects.all()
serializer = PiePizzaSerializer(pizzas, many=True)
return Response(serializer.data)
class ToppingSerializer(serializers.Serializer):
name = serializers.CharField(required=True, allow_blank=False, max_length=50)
class PizzaSerializer(serializers.Serializer):
name = serializers.CharField(required=True, allow_blank=False, max_length=50)
toppings = ToppingSerializer(many=True, required=False)
class PieToppingSerializer(serializers.ModelSerializer):
class Meta:
model = Topping
fields = ('name',)
class PiePizzaSerializer(serializers.ModelSerializer):
name = serializers.CharField(required=True)
toppings = PieToppingSerializer(many=True, required=False)
class Meta:
model = Pizza