如何序列化自定义多对多模型 Django?

How can I serialize custom many-to-many model django?

我在数据库中有 3 个表:News、CustomUser(不重要)和 Comment:

class News(models.Model):
    date = models.DateTimeField(auto_now_add=True)
    title = models.CharField(max_length=200)
    text = models.TextField()
    image = models.ImageField(upload_to='news_images/', blank=True)
    author = models.ForeignKey(CustomUser, on_delete=models.SET_DEFAULT, blank=True, default=1)
    tags = models.ManyToManyField(Tags, blank=True)
    published = models.BooleanField(default=False)
    comments = models.ManyToManyField(
        CustomUser,
        related_name='author',
        through='Comments.Comment',
        blank=True,
    )

class Comment(models.Model):
    date = models.DateTimeField(auto_now_add=True)
    text = models.TextField()
    author = models.ForeignKey(CustomUser, on_delete=models.SET_NULL, null=True)
    event = models.ForeignKey(News, on_delete=models.CASCADE, parent_link=True)

如您所见,评论是一个自定义的多对多模型,它链接用户和新闻,并添加一些额外的数据(评论本身的文本)。 我使用 DRF,所以我需要序列化它。我需要新闻序列化程序来包含评论列表及其所有字段(如作者字段,如下面的屏幕截图所示)。但是当我收到其中一条新闻时,我看到:

{"id":2,"author":{"username":"Admin","email":"alexsiid29@gmail.com","first_name":"","last_name":""},"tags":[],"comments":[1],"date":"15.08.2021 10:10","title":"Тест2","text":"тестовая 2","image":"http://127.0.0.1:8000/news_images/%D0%91%D0%B5%D0%B7%D1%8B%D0%BC%D1%8F%D0%BD%D0%BD%D1%8B%D0%B9.png","published":true}

评论:"comments":[1]

当我在视图函数执行期间打印时:

self.object = News.objects.filter(pk=pk).first()
print(self.object.comments.all())

我得到这个:<QuerySet [<CustomUser: Admin>]> 所以,我得到的不是评论的正常表示,而是作者 ID。 有我的序列化程序:

class CommentSerializer(serializers.ModelSerializer):
    author = CustomUserSerializer(source='author.id')
    event = NewsSerializer(source='event.id')

class NewsSerializer(serializers.ModelSerializer):
    author = CustomUserSerializer(read_only=True)
    tags = TagSerializer(required=False, allow_null=True, many=True)
    comments = serializers.PrimaryKeyRelatedField(allow_null=True, many=True, read_only=True)

那么,如何序列化这些表,或者以不同的方式组织它们?

P.S。 我也试过 StringRelatedField 而不是 PrimaryRelatedField,但它 returns 作者的名字。

  1. 您的代码中有错字:News 模型中的 comments 必须与 Comment 模型链接,而不是与 CustomUser 链接。这就是为什么你得到 <QuerySet [<CustomUser: Admin>]>.

  2. 为了解决“我需要新闻序列化程序来包含评论列表及其所有字段”,我将执行以下操作:

class CommentSerializer(serializers.ModelSerializer):
    author = CustomUserSerializer()

    class Meta:
        model = Comment
        exclude = ('event',)  # in your particular case


class NewsSerializer(serializers.ModelSerializer):
    author = CustomUserSerializer(read_only=True)
    tags = TagSerializer(required=False, allow_null=True, many=True)
    comments = CommentSerializer(many=True)
    
    class Meta:
        model = News
        fields = "__all__"

我建议您将 event 排除在 CommentSerializer 中,因为您的 NewsSerializer 中会有此信息,因此不会对每个 comment 重复。