Как я могу сериализовать пользовательскую модель "многие-ко-многим" 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, но он возвращает имя автора.

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

Вернуться на верх