django序列化程序动态设置属性
是否可以动态设置django序列化程序动态设置属性,django,serialization,Django,Serialization,是否可以动态设置序列化程序的属性 CONTEXT_CLASSES = dict() contexts = ['EmailContext', 'SmsMessageContext',...] for ctx in contexts: Ctx_class = getattr(sys.modules[__name__], f'{ctx}Serializer') ctx_class_instance = Ctx_class(many=False, required=False, rea
序列化程序的属性
CONTEXT_CLASSES = dict()
contexts = ['EmailContext', 'SmsMessageContext',...]
for ctx in contexts:
Ctx_class = getattr(sys.modules[__name__], f'{ctx}Serializer')
ctx_class_instance = Ctx_class(many=False, required=False, read_only=True)
attr_name = ctx.split('Context')[0].lower() + '_ctx'
CONTEXT_CLASSES[attr_name] = ctx_class_instance
class ContextContainerSerializer(serializers.ModelSerializer):
for attr_name, instance in CONTEXT_CLASSES.items():
# set attributes somehow
class Meta:
...
fields = tuple([value[0] for value in CONTEXT_CLASSES.values()])
将其放入\uuuu init\uuuu
将不起作用,因为类Meta
在它之前执行,并设置字段变量,该变量已包含属性名称,并将引发django.core.exceptions.improverlyconfigured
您可以在初始化时设置属性
class ContextContainerSerializer(serializers.ModelSerializer):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# should be able to access "self.Meta"
for attr_name, instance in CONTEXT_CLASSES.items():
setattr(self.Meta, attr_name, instance)
或者要获得更动态的控制/模式,请使用元类
from rest_framework.serializers import SerializerMetaclass
class ExtraContextMetaclass(SerializerMetaclass):
def __new__(cls, name, bases, dct):
"""
:param name: name of class to be created
:param bases: sub classes
:param dct: other attributes
:return:
"""
new_class = super().__new__(cls, name, bases, dct)
new_class.Meta = cls.dynamic_meta(new_class.Meta)
return new_class
@classmethod
def dynamic_meta(cls, old_meta):
# create a class called "Meta"
new_meta = type('Meta', (), dict(fields=None))
# copy over required attributes from original Meta
new_meta.model = old_meta.model
new_meta.fields = list(old_meta.fields[:])
# set new attributes dynamically
for attr_name, instance in CONTEXT_CLASSES.items():
setattr(new_meta, attr_name, instance)
return new_meta
class ContextContainerSerializer(serializers.ModelSerializer,
metaclass=ExtraContextMetaclass):
class Meta:
model = Model
fields = ['some_field']
您可以尝试ContextContainerSerializer(context=context\u类)。并通过self.context.get(attr_name)在类序列化中获取第一个将不起作用,因为我正在定义类元
中的字段,该字段在\uuuu init\uu
之前执行,第二个版本似乎也会引起问题,因为\uu new\u
在类元
之前执行(很抱歉之前没有添加元-我现在更新了代码)我已经更新了答案以反映更新后的问题