如何将字段添加到与另一个模型具有反向关系的模型序列化程序

How can I add a field to a model serializer that has a reverse relationship with another model

我有两个模型。小说和评论模型。它们是:

class Fiction(models.Model):
    """
    Model that encopasses a Movie, TV Series, book or similar
    """
    MOVIE       = 1
    TV_SERIES   = 2
    BOOK        = 3
    PODCAST     = 4

    TYPE = (
        (MOVIE, 'Movie'),
        (TV_SERIES, 'TV-Series'),
        (BOOK, 'Book'),
        (PODCAST, 'Podcast')
    )


    title = models.CharField(max_length=50)
    description = models.CharField(max_length=200)
    active = models.BooleanField(default=True)
    created = models.DateTimeField(auto_now_add=True)
    platform = models.ForeignKey(
        StreamPlatform, 
        on_delete=models.SET_NULL, 
        related_name='fictions',
        null = True
        )
    type = models.PositiveSmallIntegerField(
        choices = TYPE,
        default = MOVIE
    )

    def __str__(self):
        return self.title

class Review(models.Model):
    """
    model for fiction reviews from users
    """
    rating = models.PositiveSmallIntegerField(validators=[MinValueValidator(1), MaxValueValidator(5)])
    fiction = models.ForeignKey(Fiction, on_delete=models.CASCADE, related_name="reviews")
    description = models.CharField(max_length=200, null = True, blank =True)
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)

    def __str__(self):
        return str(self.rating) + " | " + str(self.fiction)

    class Meta:
        ordering = ['-created']

还有两个序列化器 小说

class FictionSerializer(serializers.ModelSerializer):
    """
    serializer for Movie model
    """

    class Meta:
        model = Fiction
        fields = "__all__"

待审核

class ReviewSerializer(serializers.ModelSerializer):

    class Meta:
        model = Review
        fields = ['rating', 'fiction', 'description']

我希望能够在小说连载程序中显示评论的评分。我试过类似的东西:

rating = serializers.ReadOnlyField(source='reviews.rating')

但是没用。有人有想法吗?

由于您添加了 reviews 作为相关名称,您可以使用它。 这是一个适合您的工作示例。 (我为此创建了一个小项目,所以这绝对有效)

class ReviewRatingSerializer(serializers.ModelSerializer):

    class Meta:
        model = Review
        fields = ('rating', )



class FictionSerializer(serializers.ModelSerializer):
    """
    serializer for Movie model
    """
    reviews = ReviewRatingSerializer(many=True)

    class Meta:
        model = Fiction
        fields = "__all__"

如果您想一次 return 大量小说项目,这可能会导致大量数据库查询。 要解决此问题,您应该在 views.py

中使用 prefetch_related

这是一个列表视图的简单示例。

class GetFictionMovies(ListAPIView):
    pagination_class = None
    serializer_class = FictionSerializer

    def get_queryset(self):
        queryset = Fiction.objects.all().prefetch_related('reviews')
        return queryset

输出将与此类似。

[
    {
        "id": 1,
        "reviews": [
            {
                "rating": 3
            },
            {
                "rating": 4
            }
        ],
        "title": "Starwars",
        "description": "asdasd",
        "active": true,
        "created": "2021-06-27T16:28:55.521748Z",
        "type": 1
    },
    {
        "id": 2,
        "reviews": [
            {
                "rating": 5
            },
            {
                "rating": 2
            }
        ],
        "title": "LOTR",
        "description": "asdasd",
        "active": true,
        "created": "2021-06-27T16:29:03.227639Z",
        "type": 1
    },
    {
        "id": 3,
        "reviews": [
            {
                "rating": 4
            },
            {
                "rating": 3
            }
        ],
        "title": "GODFATHER",
        "description": "asdasd",
        "active": true,
        "created": "2021-06-27T16:34:45.171444Z",
        "type": 1
    }
]

我对您的建议是始终检查对数据库的查询次数,并尽量避免重复调用数据库。