django REST framework - limited queryset for neste

2019-01-22 02:46发布

I have a ModelSerializer, but by default it serializes all the objects in my model. I would like to limit this queryset to only the most recent 500 (as opposed to all 50 million). How do I do this?

What I have currently is the following:

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

The reason I don't think I can just specify the queryset in my viewset is that this is in fact the nested portion of another serializer.

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')

2条回答
萌系小妹纸
2楼-- · 2019-01-22 03:25

In your View Set you may specify the queryset like follows:

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

I think what you are looking for is the SerializerMethodField.

So your code would look as follows:

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

The one catch is that the SerializerMethodField is read only.

查看更多
放荡不羁爱自由
3楼-- · 2019-01-22 03:29

You may use source parameter

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

and in serializer

items = ItemSerializer(many=True, source='get_items', )
查看更多
登录 后发表回答