django REST框架 - 嵌套ModelSerializer的有限查询集?

jon*_*omo 28 django serialization django-rest-framework

我有一个ModelSerializer,但默认情况下它会序列化我的模型中的所有对象.我想将此查询集限制为仅最近的500(而不是所有5000万).我该怎么做呢?

我目前的情况如下:

class MyModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = MyModel
Run Code Online (Sandbox Code Playgroud)

我不认为我可以在视图集中指定查询集的原因是,这实际上是另一个序列化程序的嵌套部分.

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)
Run Code Online (Sandbox Code Playgroud)

views.py

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

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')
Run Code Online (Sandbox Code Playgroud)

Joh*_*dt6 41

在视图集中,您可以指定查询集,如下所示:

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
Run Code Online (Sandbox Code Playgroud)

我想你要找的是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
Run Code Online (Sandbox Code Playgroud)

SerializerMethodField唯一的问题是它是只读的.

  • 只是一个细节.你不需要在SerializerMethodField(...)上指定'get_items',因为它总是使用"get_"+属性名称自动推断 (8认同)

小智 10

您可以使用source参数

class Container(models.Model):
    ...
    def get_items(self):
        return self.items[:500]
Run Code Online (Sandbox Code Playgroud)

并在序列化器中

items = ItemSerializer(many=True, source='get_items', )
Run Code Online (Sandbox Code Playgroud)