Как я могу сериализовать пользовательскую модель "многие-ко-многим" 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, но он возвращает имя автора.
В вашем коде есть опечатка:
commentsв моделиNewsдолжен быть связан с моделью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.