Python Django框架中如何复用Serializer序列化器
Django REST Framework Serializer实例复用方案
基础说明
DRF的Serializer设计本身就将数据绑定逻辑放在实例化阶段,每次新建实例的内存开销极低,官方所有示例均遵循每次请求新建实例的规范,常规场景下不需要刻意复用实例。如果你是想要避免重复写Serializer实例化的重复代码、复用自定义的Serializer逻辑,可参考以下两种实现方案。
方案1:强制复用同一个Serializer实例(不推荐生产使用)
如果确实有特殊场景需要复用同一个实例,可手动重置Serializer内部的状态属性,修改后的Service代码如下:
from django.http.response import JsonResponse from rest_framework import status from models import Instrument from serializers import InstrumentsSerializer class InstrumentsService(): def __init__(self): # 初始化阶段仅创建空Serializer实例,不绑定数据 self.serializer = InstrumentsSerializer() def get_instruments_by_type(self, instrument_type: str): if instrument_type is None: raise ValueError("Value type None is not acceptable for 'instrument_type'") # 原代码这里有逻辑问题:filter不会修改原queryset,需要链式调用或者重新赋值 instruments = Instrument.objects.filter(instrument_type__icontains=instrument_type).all() # 手动绑定数据、重置所有缓存状态 self.serializer.instance = instruments self.serializer.many = True self.serializer.initial_data = None self.serializer._data = None self.serializer._errors = None self.serializer._validated_data = None return self.serializer.data def add_instrument(self, instrument_data: dict): # 手动绑定待校验数据、重置所有缓存状态 self.serializer.instance = None self.serializer.many = False self.serializer.initial_data = instrument_data self.serializer._data = None self.serializer._errors = None self.serializer._validated_data = None if self.serializer.is_valid(): self.serializer.save() return self.serializer.data
注意:该方案存在严重的线程安全风险,如果你的Service是单例模式,并发请求下会出现数据串用的问题,且一旦漏清某个内部属性就会导致逻辑错误,仅做原理展示,不推荐生产使用。
方案2:封装实例化逻辑,复用Serializer类定义(推荐)
这是更符合DRF设计规范的“复用”方式,你复用的是Serializer的自定义逻辑,同时保留原生实例的状态隔离、线程安全特性,仅把重复的实例化逻辑封装处理:
from django.http.response import JsonResponse from rest_framework import status from models import Instrument from serializers import InstrumentsSerializer class InstrumentsService(): def __init__(self): # 仅绑定Serializer类,每次请求动态创建实例 self.serializer_cls = InstrumentsSerializer def get_instruments_by_type(self, instrument_type: str): if instrument_type is None: raise ValueError("Value type None is not acceptable for 'instrument_type'") instruments = Instrument.objects.filter(instrument_type__icontains=instrument_type).all() return self.serializer_cls(instruments, many=True).data def add_instrument(self, instrument_data: dict): serializer = self.serializer_cls(data=instrument_data) if serializer.is_valid(): serializer.save() return serializer.data
- 该方案没有额外的维护成本,也不会引入并发风险,同时满足了复用Serializer逻辑、减少重复代码的需求。
内容的提问来源于stack exchange,提问作者KZiovas
相关产品推荐
相关产品推荐

