如何序列化自定义多对多模型 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 作者的名字。
您的代码中有错字:News
模型中的 comments
必须与 Comment
模型链接,而不是与 CustomUser
链接。这就是为什么你得到 <QuerySet [<CustomUser: Admin>]>
.
为了解决“我需要新闻序列化程序来包含评论列表及其所有字段”,我将执行以下操作:
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
重复。
我在数据库中有 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 作者的名字。
您的代码中有错字:
News
模型中的comments
必须与Comment
模型链接,而不是与CustomUser
链接。这就是为什么你得到<QuerySet [<CustomUser: Admin>]>
.为了解决“我需要新闻序列化程序来包含评论列表及其所有字段”,我将执行以下操作:
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
重复。