django - Django Serializer - 决定在运行时序列化哪些字段
问题描述
我正在使用 DRF 并且有一个序列化的模型。有时我想在发送到 api 端点的数据中包含所有字段,有时我只需要属性的子集(例如列表视图与编辑视图)。是否可以在一个序列化程序中声明所有字段,然后在调用序列化程序时只指定一个子集。
这是我想做的一个例子:
queryset = Foo.objects.filter(active=True)
FooSerializer(queryset, many=True, fields=["id", "title"])
然后我可以使用这个输出来填充 HTML 选择元素的选项。
同时FooSerializer
看起来像这样:类
FooSerializer(serializers.ModelSerializer):
id = serializers.ReadOnlyField()
class Meta:
model = ProgressNoteCustomType
fields = ( 'id', 'title', 'modified', 'active', 'user' )
read_only_fields = ['id']
虽然我可以编写另一个序列化程序,它在定义中只有id
andtitle
字段Meta
,但它不是DRY
.
然后我有另一个场景,我想显示一个列表视图,用户可以在其中单击一个项目并对其进行编辑 - 这里我只想显示title
、modified
和active
。写类似的东西FooSerializer(queryset, many=True, fields=["id", "title", "active"])
似乎是合适的解决方案,但无效。
我真的想避免为这 3 种不同的场景使用 3 种不同的序列化(其中常规FooSerializer(instance)
是返回序列化程序中定义的所有字段的编辑/查看默认值)
解决方案
class DynamicFieldsModelSerializer(serializers.ModelSerializer):
"""
A ModelSerializer that takes an additional `fields` argument that
controls which fields should be displayed.
"""
def __init__(self, *args, **kwargs):
# Don't pass the 'fields' arg up to the superclass
fields = kwargs.pop('fields', None)
exclude = kwargs.pop('exclude', None)
# Instantiate the superclass normally
super(DynamicFieldsModelSerializer, self).__init__(*args, **kwargs)
if fields is not None:
# Drop any fields that are not specified in the `fields` argument.
allowed = set(fields)
existing = set(self.fields.keys())
for field_name in existing - allowed:
self.fields.pop(field_name)
if exclude is not None:
not_allowed = set(exclude)
for exclude_name in not_allowed:
self.fields.pop(exclude_name)
这是您需要的,使用如下:
FooSerializer(DynamicFieldsModelSerializer):
....
在views.py中:
FooSerializer(queryset, many=True, fields=["id", "title"])
或者
FooSerializer(queryset, many=True, exclude=['modified', 'active', 'user' ])
医生在这里。
推荐阅读
- azure - Azure 门户 SqlAzureExtension 扩展无法加载
- c++ - 在 C++ 中将美元转换为美分
- html - 将可点击的 DIV 并排放置在网格中。最后一个 DIV 给出问题
- multithreading - 是否可以在当前线程中对 Tokio 的当前线程进行工作?
- javascript - 无法使用 CSV 数据绘制 Highchart 饼图
- c++ - C ++中的“字符串()+字符”
- c - 如何使指针起作用?
- git - 如何在 git 存储库中编辑私有方法以使其可维护
- graphql - Apollo 链路状态错误 - 向源发送请求时出错
- public-key-encryption - base58 不能得到 34 个字符的结果(就像比特币地址那样),但是 68 个字符