django - 列出 Django Rest Framework 序列化程序中所需字段的名称(并忽略父字段)
问题描述
我要做的是获取序列化程序中所有字段的列表:
- 不包含作为
required=False
参数。 - 不要来自父序列化程序。
例如,如果我有像这样的序列化程序:
class ParentSerializer(serializers.Serializer):
parent_field = serializers.IntegerField
class ChildSerializer(ParentSerializer):
child_field_required = serializers.IntegerField
child_field_not_required = serializers.IntegerField(required=False)
我希望得到的输出是:
['child_field_required']
我发现我可以获得已声明字段的有序列表,例如:
self.get_serializer().get_fields()
>> OrderedDict([
('parent_field', IntegerField()),
('child_field_required', IntegerField()),
('child_field_not_required', IntegerField(required=False)),
])
但我一直无法超越这一步。
解决方案
由于您继承自serializers.Serializer
,因此必须在类主体上显式声明所有字段(与serializers.ModelSerializer
遍历模型层以自动生成字段不同)。在这种情况下,您可以这样做:
parent_field_names = {
name
for base in type(instance).__bases__
if hasattr(base, '_declared_fields')
for name in base._declared_fields
}
desired_fields = [
(name, field)
for name, field in instance.get_fields().items()
if name not in parent_field_names and
field._kwargs.get('required', None) is not False
]
假设instance
是一个serializers.Serializer
实例。parent_field_names
指的是 O(1) 查找的集合。
以上取决于几个实现细节:
serializers.Serializer
--的元类serializers.SerializerMetaclass
将声明的字段分配为类属性_declared_fields
dict- 整个构造(
__new__
),serializers.Field
该类将最初传递的关键字参数作为_kwargs
实例上的属性保留给新创建的字段实例
笔记:
如果您想让它也适用于
serializers.ModelSerializer
的模型字段遍历,即对于未声明的字段或覆盖的字段Meta
,您需要检查get_fields
每个字段,然后仅获取当前序列化程序中定义的字段serializers.SerializerMetaclass
pop
_declared_fields
在创建属性时从类属性中关闭字段,因此您无法访问类中的字段。否则,我们可以在基类上使用属性检查来查看是否在那里定义了任何字段,这将导致代码更短。
推荐阅读
- c++ - 这行代码中“转”的目的是什么?
- r - 从闰年的数据中引导/模拟
- npm - NPM 过时的命令未显示完整列表
- javascript - 为什么在 JavaScript 中运行时输出“未定义”?
- html - 如何在 create-react-app 中为 index.html 指定 Cache-Control 标头
- memory - 如何将函数复制到内存中的缓冲区中?
- micrometer - 通过 Micrometer 使用 Servlet 过滤器的 HTTP 指标
- nodemcu - Expressif esp8266 开发套件 c 的 GPIO 映射
- javascript - 自动更新定时器/自动重置定时器
- machine-learning - 究竟包含 Word2Vec 的词向量(或通常是词嵌入,但我们可以保留 Word2Vec)