如何为Django REST Framework序列化器返回的字典添加类型提示?
给DRF序列化器的validated_data添加类型提示的几种方法
方法一:用TypedDict定义验证后的数据结构
先定义一个与validated_data结构完全匹配的TypedDict类型,再给视图中的变量加上类型注解,就能让IDE识别所有字段的类型。
- 定义TypedDict(可放在serializers.py或单独的types.py文件中):
from typing import TypedDict from myapp.models import ObjectOne class ExampleValidatedData(TypedDict): field_one: str field_two: str field_three: str object_one: ObjectOne
- 在视图中使用类型注解:
def post(self, request): body_serializer = ExampleSerializer(data=request.data) body_serializer.is_valid(raise_exception=True) body_data: ExampleValidatedData = body_serializer.validated_data # 现在IDE会自动提示object_one是ObjectOne类型 object_one = body_data['object_one']
方法二:给序列化器添加泛型类型注解
通过自定义泛型序列化器类,指定validated_data的类型,访问serializer.validated_data时会自动推导类型。
- 自定义泛型序列化器和TypedDict:
from rest_framework import serializers from typing import TypeVar, Generic from myapp.models import ObjectOne ValidatedDataT = TypeVar('ValidatedDataT') class TypedSerializer(serializers.Serializer, Generic[ValidatedDataT]): @property def validated_data(self) -> ValidatedDataT: return super().validated_data class ExampleValidatedData(TypedDict): field_one: str field_two: str field_three: str object_one: ObjectOne class ExampleSerializer(TypedSerializer[ExampleValidatedData]): field_one = serializers.CharField(required=True, help_text='field_one') field_two = serializers.CharField(required=True, help_text='field_two') field_three = serializers.CharField(required=True, help_text='field_three') def validate(self, attrs): # 修正原代码问题:从attrs中获取field_one的值 object_one: ObjectOne = ObjectExample.objects.get(field=attrs['field_one']) attrs['object_one'] = object_one return attrs
- 在视图中直接使用:
def post(self, request): body_serializer = ExampleSerializer(data=request.data) body_serializer.is_valid(raise_exception=True) body_data = body_serializer.validated_data # 自动识别为ExampleValidatedData类型,所有字段都有类型提示 object_one = body_data['object_one']
方法三:单个字段的类型断言(简单场景)
如果不想定义复杂类型结构,可在取字段时直接给变量加类型注解:
def post(self, request): body_serializer = ExampleSerializer(data=request.data) body_serializer.is_valid(raise_exception=True) body_data = body_serializer.validated_data # 直接给变量指定类型 object_one: ObjectOne = body_data['object_one']
这种方式只针对单个字段生效,整个body_data字典无类型提示,适合简单场景。
内容的提问来源于stack exchange,提问作者Andres melendes
相关产品推荐
相关产品推荐

