如何在 django rest 框架中选择特定字段?

Yri*_*uns 9 python django django-rest-framework

例如,我有一个Person模型及其序列化程序

class Person(models.Model):
    first_name = models.CharField(max_length=255)
    last_name = models.CharField(max_length=255)
    sex = models.IntegerField()
    phone = models.CharField(max_length=255)


class SimplePersonSerializer(serializer.ModelSerializer):
    class Meta:
        model = Person
        fields = ('first_name', 'last_name')
Run Code Online (Sandbox Code Playgroud)

然后在我的视图函数中,我可以:

@api_view(['GET'])
def people(request):
    people = Person.objects.all()
    data = SimplePersonSerializer(people, many=True).data
    return Response(data)
Run Code Online (Sandbox Code Playgroud)

但是,当我使用 对其进行分析时django-debug-toolbar,它显示序列化程序要求SQL Server选择Person模型的所有字段,尽管我只需要first_namelast_name

我知道我可以改变people = Person.objects.all(),以people = Person.objects.all().only('first_name', 'last_name')使其。但我想知道我是否可以在序列化程序中执行此操作。

shi*_*gar 10

您可以dynamic field serializer为此创建并动态获取字段数据。

class DynamicFieldsModelSerializer(serializers.ModelSerializer):
    """
    A ModelSerializer that takes an additional `fields` argument that
    controls which fields should be displayed.
    """

    def __init__(self, *args, **kwargs):
        # Don't pass the 'fields' arg up to the superclass
        fields = kwargs.pop('fields', None)

        # Instantiate the superclass normally
        super(DynamicFieldsModelSerializer, self).__init__(*args, **kwargs)

        if fields is not None:
            # Drop any fields that are not specified in the `fields` argument.
            allowed = set(fields)
            existing = set(self.fields.keys())
            for field_name in existing - allowed:
                self.fields.pop(field_name)

class SimplePersonSerializer(DynamicFieldsModelSerializer):
    class Meta:
        model = Person
        fields = '__all__' 
Run Code Online (Sandbox Code Playgroud)

然后你可以像这样在你的视图中使用它。

@api_view(['GET'])
def people(request):
    fields = ('first_name', 'last_name')
    people = Person.objects.all().only(fields)
    data = SimplePersonSerializer(people, many=True, fields = fields).data
    return Response(data)
Run Code Online (Sandbox Code Playgroud)

这有帮助,improve performance因为它只会获取所需的数据。(Person.objects.all().only('first_name', 'last_name')用于获取特定数据时)