Подтвердить что ты не робот

Django REST framework - ограниченный набор запросов для вложенного ModelSerializer?

У меня есть ModelSerializer, но по умолчанию он сериализует все объекты в моей модели. Я хотел бы ограничить этот набор запросов только последними 500 (в отличие от всех 50 миллионов). Как это сделать?

В настоящее время у меня есть следующее:

class MyModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = MyModel

Причина, по которой я не могу просто указать запрос в моем представлении, заключается в том, что на самом деле это вложенная часть другого сериализатора.

models.py

class Container(models.Model):
    size  = models.CharField(max_length=20)
    shape = models.CharField(max_length=20)

class Item(models.Model):
    container = models.ForeignKey(Container, related_name='items')
    name  = models.CharField(max_length=20)
    color = models.CharField(max_length=20)

views.py

class ContainerViewSet(viewsets.ModelViewSet):
    queryset = Container.objects.all()  # only a handful of containers
    serializer_class = ContainerSerializer

serializers.py

class ItemSerializer(serializers.ModelSerializer):
    class Meta:
        model = Item
        fields = ('name', 'color')

class ContainerSerializer(serializers.ModelSerializer):
    items = ItemSerializer(many=True)  # millions of items per container
    class Meta:
        model = Container
        fields = ('size', 'shape', 'items')
4b9b3361

Ответ 1

В вашем представлении просмотра вы можете указать набор запросов, как показано ниже:

from rest_framework import serializers, viewsets

class MyModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = MyModel

class MyModelViewSet(viewsets.ModelViewSet):
    queryset = MyModel.objects.all()[:500]
    serializer_class = MyModelSerializer

Я думаю, что вы ищете SerializerMethodField.

Таким образом, ваш код будет выглядеть следующим образом:

class ContainerSerializer(serializers.ModelSerializer):
    items = SerializerMethodField('get_items')

    class Meta:
        model = Container
        fields = ('size', 'shape', 'items')

    def get_items(self, container):
        items = Item.objects.filter(container=container)[:500]  # Whatever your query may be
        serializer = ItemSerializer(instance=items, many=True)
        return serializer.data

Единственное, что означает SerializerMethodField только для чтения.

Ответ 2

Вы можете использовать параметр источника

class Container(models.Model):
    ...
    def get_items(self):
        return self.items[:500]

и в сериализаторе

items = ItemSerializer(many=True, source='get_items', )