我有一个动态序列化器,我将API调用的参数传递到序列化器中,以从相关的模型类中筛选特定的字段。我通过利用序列化器的__init__
函数直接设置self.Meta.fields
来实现这一点,否则这是我配置的默认字段集。给定一个有3个字段id
、description
和trigger
的模型,当我进行一个未过滤的调用/api/endpoint
时,我得到了我所期望的,一个包含模型中所有字段的json对象列表。然后,当我进行一个过滤调用时,即/api/endpoint?fields=id
,我也得到了我所期望的结果,一个只包含id
字段的列表结果。然而,当我进行另一个未过滤的调用时,我仍然得到一个只有id
字段的对象列表。从现在开始我唯一能得到我想要的就是打一个新的过滤电话。下面是我的序列化器代码。
class BaseSerializer(serializers.ModelSerializer):
# id comes from `serializers.ModelSerializer`
description = DescriptionSerializer()
trigger = TriggerSerializer()
class SerializerA(BaseSerializer):
def __init__(self, *args, **kwargs):
fields = kwargs.pop("fields", None)
super().__init__(*args, **kwargs)
if fields:
self.Meta.fields = fields <--- this does NOT reset between calls
class Meta:
model = ImplIdDescriptionTriggerModelA # there are more ImplModels...
fields = '__all__'
class ParameterCaptureSerializer(BaseSerializer):
class Meta:
model = BaseIdDescriptionTriggerModel
fields ='__all__'
def to_representation(self, instance):
fields = None <--- I could set this to DEFAULT_FIELDS and fix the problem, but what about the Meta state between calls? Whats that about?
request = self.context.get("request")
if request:
params = request.query_params.get("fields")
if params:
# parses params and checks them against a set of allowed values or throws
# an rest_framework exception with a response showing allowed fields
fields = parse_fields(field_param=params, allowed=ALLOWED_FIELDS)
if isinstance(instance, ImplIdDescriptionTriggerModelA):
return SerializerA(instance=instance, fields=fields, context=self.context).data
elif isinstance(instance, ImplIdDescriptionTriggerModelB):
return SerializerB(instance=instance, fields=fields, context=self.context).data
# new document subtypes must be added here
else:
raise NotImplementedError
我认为唯一有意义的解决方案是将字段默认为ALLOWED_FIELDS,以解决这个问题,而不是引入并发问题。
1条答案
按热度按时间bcs8qyzn1#
首先,如果您在
__init__
上更改self.META
-您将更改所有示例的对象Meta。第二-DRF文档中的信息是错误的!!https://www.django-rest-framework.org/api-guide/serializers/#dynamically-modifying-fields-这是错误的解决方案。
在第三-我解决你的问题在我的谈话有:https://youtu.be/IycQNgzFKwE?si=rbucOYDy-xK5jzfU&t=170
最后,工作解决方案: