Как ограничить количество записей в сериализаторе
Здравствуйте, как ограничить количество результатов с помощью сериализатора?
Вкратце, есть таблица комментариев, которая может содержать различные типы постов.
class CourseComment(models.Model):
user = models.ForeignKey(User, on_delete=models.PROTECT)
content = models.TextField()
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
object_id = models.PositiveIntegerField()
content_object = GenericForeignKey('content_type', 'object_id')
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
и вот соответствующая таблица
class CourseMessage(models.Model):
course_id = models.ForeignKey(Course, on_delete=models.PROTECT)
author_id = models.ForeignKey(User, on_delete=models.PROTECT)
text = models.TextField() # RAW Format must exclude specials chars before publish
is_pinned = models.BooleanField(default=False)
comments = GenericRelation('CourseComment')
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
Я сделал сериализатор в соответствии с документацией https://www.django-rest-framework.org/api-guide/relations/
class CourseMessages(serializers.ModelSerializer):
user = Author(source='authorid', read_only=True)
files = MessageFiles(source='coursemessageattachedfile_set', many=True)
message_comments = MessageComments(source='comments', many=True, read_only=True)
class Meta:
model = CourseMessage
fields = ['text', 'updated_at', 'user', 'files', 'message_comments']
class MessageComments(serializers.RelatedField):
def to_representation(self, value):
ct = ContentType.objects.get_for_model(value)
serializer = Comments(value, read_only=True, source='last_comments')
return serializer.data
class Comments(serializers.ModelSerializer):
author = Author(source='user', read_only=True)
class Meta:
model = CourseComment
fields = ['content', 'author']
Все работает хорошо, но хотелось бы видеть первые 3 комментария. Может кто-то сталкивался с такой проблемой или может подсказать как лучше сделать. Я получаю эти данные для детальной страницы RetrieveAPIView. Первые три комментария нужны для отображения на передней панели.
требования Django==3.2.5 djangorestframework==3.12.4
Заранее спасибо :)
Я думаю, что вы ничего не получите, указав сериализатору возвращать подмножество набора результатов. Я думаю, что лучшим способом является фильтрация подмножества при составлении запроса или фильтрация массива после сериализации:
result_set = CourseComment.objects.all()[:3] # model
three_first = Comment(result_set, many=True).data # serializer
или
result_set = CourseComment.objects.all() # model
three_first = Comment(result_set, many=True).data[:3] # serializer
Или вы можете даже отправить подмножество набора результатов в сериализатор:
result_set = CourseComment.objects.all() # model
three_first = Comment(result_set[:3], many=True).data # serializer
Если вы используете набор запросов как:
class ViewName(generics.RetriveAPIView):
permission_classes = [IsAuthenticated]
serializer_class = Comments
queryset = CourseComment.objects.all()
тогда вы можете использовать внутри вашей функции списка:
def list(self, request, *args, **kwargs):
serializer = Comments(self.get_queryset().order_by('-id')[:3], many = True)
Надеемся, что это сработает для вас.
Я думаю, что вы ищете SerializerMethodField()
Итак, ваш код должен выглядеть следующим образом:
class CourseMessages(serializers.ModelSerializer):
user = Author(source='authorid', read_only=True)
files = MessageFiles(source='coursemessageattachedfile_set', many=True)
message_comments = serializers.SerializerMethodField()
def get_message_comments(self, obj):
message_comments = Comments.objects.all()[:3]
return MessageComments(message_comments, source='comments', many=True, read_only=True).data
class Meta:
model = CourseMessage
fields = ['text', 'updated_at', 'user', 'files', 'message_comments']