动态添加字段到 drf 序列化器
Add field to drf serializer dynamically
我有一个 API 端点,return 我的一个模型的对象列表。
我有一个非常简单的序列化程序,目前 return 包含所有模型字段。
我现在需要的是向这个序列化程序添加另一个字段,该字段是通过对模型字段之一应用逻辑和另一个也是动态计算的数据结构来计算的——但每次调用都应该只计算一次API.
为每个 API 调用而不是为序列化器 returns 的每个对象向序列化程序提供此结构的方法是什么?
我的 ModelViewSet(没有额外字段)非常简单:
class MyModelViewset(ModelViewSet):
queryset = SomeModel.objects.all()
serializer_class = SomeModelSerializer
关于如何实现这一点的一些建议:
- 要仅计算一次并在序列化程序中使用它,您应该将其添加到序列化程序中 context。
- 您可以创建 @property in your
SomeModel
class and it can be exposed via serializer fields as read only. Django has also @cached_property,这样值只计算一次,并且只要实例存在就一直存在
- 如果你想计算一些东西,你可以使用 SerializerMethodField 字段(你可以访问那里的序列化程序上下文)。
只是一个关于如何使用它的简单示例。
class MyModelViewset(ModelViewSet):
queryset = SomeModel.objects.all()
serializer_class = SomeModelSerializer
def get_serializer_context(self):
context = super().get_serializer_context()
context['my_value'] = [] # calculate something here, you have access to self.request
return context
class SomeModelSerializer(serializers.ModelSerializer):
my_data = serializers.SerializerMethodField()
class Meta:
model = SomeModel
def get_my_data(self, obj):
# you have access to self.context['my_value']
# you have access to obj.some_property
return my_data
我有一个 API 端点,return 我的一个模型的对象列表。 我有一个非常简单的序列化程序,目前 return 包含所有模型字段。
我现在需要的是向这个序列化程序添加另一个字段,该字段是通过对模型字段之一应用逻辑和另一个也是动态计算的数据结构来计算的——但每次调用都应该只计算一次API.
为每个 API 调用而不是为序列化器 returns 的每个对象向序列化程序提供此结构的方法是什么?
我的 ModelViewSet(没有额外字段)非常简单:
class MyModelViewset(ModelViewSet):
queryset = SomeModel.objects.all()
serializer_class = SomeModelSerializer
关于如何实现这一点的一些建议:
- 要仅计算一次并在序列化程序中使用它,您应该将其添加到序列化程序中 context。
- 您可以创建 @property in your
SomeModel
class and it can be exposed via serializer fields as read only. Django has also @cached_property,这样值只计算一次,并且只要实例存在就一直存在 - 如果你想计算一些东西,你可以使用 SerializerMethodField 字段(你可以访问那里的序列化程序上下文)。
只是一个关于如何使用它的简单示例。
class MyModelViewset(ModelViewSet):
queryset = SomeModel.objects.all()
serializer_class = SomeModelSerializer
def get_serializer_context(self):
context = super().get_serializer_context()
context['my_value'] = [] # calculate something here, you have access to self.request
return context
class SomeModelSerializer(serializers.ModelSerializer):
my_data = serializers.SerializerMethodField()
class Meta:
model = SomeModel
def get_my_data(self, obj):
# you have access to self.context['my_value']
# you have access to obj.some_property
return my_data