如何为反向和正向关系(即外键关系)编写嵌套序列化程序和通用视图

How to write nested serializer and generic views for reverse and forward relation ships i.e foreign key relationships

这是models.py

Class Customer(models.Model):
    ...

Class Project(models.Model):
    ...
    customer =  models.ForeignKey('Customer', on_delete=models.CASCADE)

Class Component1(models.Model):
    ...
    project = models.ForeignKey('Project', on_delete=models.CASCADE)

Class Component2(models.Model):
    ...
    project = models.ForeignKey("Project", on_delete=models.CASCADE)

这是serializers.py

class ProjectListSerializer(serializers.ModelSerializer):
    customer = CustomerSerializer(many=True)
    component1 = Component1Serializer()
    component2 = Component2Serializer()
    class Meta:
        model = Project

和我的views.py

class ProjectList(generics.ListAPIView):
    queryset = Project.objects.all()
    serializer_class = ProjectSerializer

该视图就像一个非嵌套序列化程序一样运行。 如何显示序列化器的全部内容?

Edit 1: If I use depth = 1 in meta class under serializer, the forward relation, i.e. customer will show but not the reverse relationship fields.

如果我执行 print(repr(ProjectList())) ,它显示的正是我想要的格式,但视图无法提供它

我是这个平台的新手,如果我可以改进问题,请评论。

好吧,我终于明白我做错了什么了。

class ProjectListSerializer(serializers.ModelSerializer):
    customer = CustomerSerializer()
    component1_set = Component1Serializer(many=True) #observe the modelname_set instead 
    component2_set = Component2Serializer(many=True) # of modelname/arbitrary name, applicable for reverse relationships.
    class Meta:
        model = Project
        depth = 1 # this is for the forward relationship (i.e. Customer over here)

如果要设置任意名称,使用

...
somename = Component1Serializer(many=True ,source = 'modelname_set')
...

同样保持many=True,因为是一对多的反向关系。 如果您不想将深度用于前向关系, 只需使用

modelname = ModelSerializer()
# i.e.
customer = CustomerSerializer()

视图不会有任何变化,但使用 ModelViewSet 和路由器配置会更容易 因此 views.py


class ProjectListViewSet(viewsets.ReadOnlyModelViewSet):
    queryset = Project.objects.all()
    serializer_class = ProjectListSerializer

如果您的查询集出于某种原因需要动态,请尝试使用 queryset = Project.objects.all().prefetch_related()