Как добавить поля в сериализатор

Я хотел бы добавить поля внешнего ключа в сериализатор DRF. Мне нужна конечная точка API с информацией о деталях публикации со всеми комментариями к этой публикации со всеми изображениями к этой публикации и с номером Likes к этой публикации.

Модели

 class Publication(models.Model):
    pub_text = models.TextField(null=True, blank=True)
    pub_date = models.DateTimeField(auto_now_add=True)
    pub_author = models.ForeignKey(User, on_delete=models.CASCADE)


class Comment(models.Model):
    com_text = models.TextField(null=True, blank=True)
    com_like = models.BooleanField(default=False)
    com_author = models.ForeignKey(User, on_delete=models.CASCADE)
    com_to_pub = models.ForeignKey(Publication, on_delete=models.CASCADE, related_name='comment_author')
    com_date = models.DateTimeField(auto_now_add=True, null=True)


class Image(models.Model):
    image = models.ImageField(upload_to='images', null=True)
    image_to_pub = models.ForeignKey(Publication, on_delete=models.CASCADE, null=True, related_name='images')

Сериализаторы

class ImageSerializer(serializers.ModelSerializer):
    class Meta:
        model = Image
        fields = ['image']


class CommentSerializer(serializers.ModelSerializer):
    class Meta:
        model = Comment
        fields = ['com_text', 'com_like', 'com_date', 'com_author']


class PublicationSerializer(serializers.ModelSerializer):
    class Meta:
        model = Publication
        fields = ['id', 'pub_text', 'pub_author', 'pub_date']

    def to_representation(self, instance):
        representation = super().to_representation(instance)
        representation['comment'] = CommentSerializer(instance.comment_author.all(), many=True).data
        representation['image'] = ImageSerializer(instance.images.all(), many=True).data
        return representation

Виды

class PublicationViewSet(viewsets.ModelViewSet):
    queryset = Publication.objects.all()
    serializer_class = PublicationSerializer


class ImageViewSet(viewsets.ModelViewSet):
    queryset = Image.objects.all()
    serializer_class = ImageSerializer


class CommentViewSet(viewsets.ModelViewSet):
    queryset = Comment.objects.all()
    serializer_class = CommentSerializer

По моей логике Like к публикации может быть передан автором комментария, если комментарий был создан. Я использовал метод <to_represtntation> для добавления полей в сериализатор Publication. Это работает так, как мне нужно, но я не уверен, что это был хороший способ. Также я не могу представить, как добавить номер Likes в сериализатор публикации.

Вы можете сделать из этого объект, например

class CommentSerializer(serializers.ModelSerializer):

public=PublicationSerializer()
class Meta:
    model = Comment
    fields = ['com_text', 'com_like', 'com_date', 'com_author']

Подход, который вы используете с методом to_representation, является правильным способом настройки сериализованных данных, но его можно улучшить для большей ясности и производительности, особенно при работе с вложенными отношениями и добавлении вычисляемых полей (например, количества лайков).

Чтобы усовершенствовать ваш подход и включить количество лайков в PublicationSerializer, мы можем:

Используйте вложенные сериализаторы для отображения комментариев и изображений к публикации. Добавьте поле likes в сериализатор PublicationSerializer, чтобы подсчитать количество лайков в комментариях, относящихся к этой публикации. Оптимизируйте подход to_representation или используйте SerializerMethodField для вычисления таких значений, как количество лайков.

В сериализаторах необходимо обновлять

from rest_framework import serializers
from .models import Publication, Comment, Image

class ImageSerializer(serializers.ModelSerializer):
    class Meta:
        model = Image
        fields = ['image']


class CommentSerializer(serializers.ModelSerializer):
    class Meta:
        model = Comment
        fields = ['com_text', 'com_like', 'com_date', 'com_author']


class PublicationSerializer(serializers.ModelSerializer):
    # Nested serializers for comments and images
    comment = CommentSerializer(source='comment_author', many=True, read_only=True)
    image = ImageSerializer(source='images', many=True, read_only=True)

    # Adding a computed field for counting likes
    likes_count = serializers.SerializerMethodField()

    class Meta:
        model = Publication
        fields = ['id', 'pub_text', 'pub_author', 'pub_date', 'comment', 'image', 'likes_count']

    def get_likes_count(self, obj):
        # Count the number of likes (True) in related comments
        return obj.comment_author.filter(com_like=True).count()

Объяснение:

  1. comment = CommentSerializer(source='comment_author', many=True, read_only=True): Это связывает поле related_name='comment_author' модели Publication с ее вложенными комментариями и использует CommentSerializer для отображения подробностей комментария.

  2. image = ImageSerializer(source='images', many=True, read_only=True): Аналогично комментариям, соединяет модель Publication со связанными с ней изображениями с помощью related_name='images' и использует ImageSerializer.

  3. likes_count = serializers.SerializerMethodField(): Это поле вычисляет общее количество лайков из связанных комментариев для каждой публикации. Метод get_likes_count использует obj.comment_author.filter(com_like=True).count() для получения количества комментариев, в которых com_like=True, для данной публикации.

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