首页 > 解决方案 > Django REST RetrieveAPIView 组合查询集

问题描述

我正在尝试构建一个查询集,它结合了两个查询结果,即类别和课程。每门课程都有一个类别外键。有没有办法将各自的课程添加到每个类别?

例子:

{
    "id": 61,
    "name": "fgfdf",
    "courses": 
        {
            "id": 1,
            "category": 61,
            "title": "mytitle"
            "active": true
        },
        {
            ...
        }
}

网址

path('dict/<pk>/', DictView.as_view(), name='detail')

楷模

class Category(models.Model):
    name = models.CharField(max_length=255, blank=False, null=False)

class Course(models.Model):
    category = models.ForeignKey(Category, on_delete=models.CASCADE, null=True)
    title = models.CharField(max_length=255, blank=False, null=False)
    active = models.BooleanField(default=True)

看法

这是我想象的,但这显然是不正确的,我做了一些研究,但找不到我需要的东西。

class DictView(RetrieveAPIView):
    queryset = Category.objects.all()
    serializer_class = CategorySerializer

    def get_queryset(self):
        queryset = Category.objects.all()
        courses = list(Course.objects.filter(category=pk))
        queryset['courses'] = courses;
        return queryset

标签: pythonmysqlsqldjangodjango-rest-framework

解决方案


一种方法是定义这样的序列化程序:

class CourseSerializer(serializers.ModelSerializer):
    class Meta:
        model = Course
        fields = "__all__"


class CategorySerializer(serializers.ModelSerializer):
    courses = CourseSerializer(source='course_set', many=True)

    class Meta:
        model = Category
        fields = "__all__"

然后,您不再需要覆盖get_queryset

如果您希望为课程应用过滤器,假设您只想要活动课程,您可以执行以下操作:

class CategorySerializer(serializers.ModelSerializer):
    courses = serializers.SerializerMethodField()

    def get_courses(self, obj):
        active_courses = obj.course_set.filter(active=True)
        return CourseSerializer(active_courset, many=True).data

    class Meta:
        model = Category
        fields = "__all__"

推荐阅读