【发布时间】:2021-04-23 07:02:56
【问题描述】:
基本上,我想要实现的是根据用户是否提供他们感兴趣的字段列表,使序列化程序中的字段列表可选地动态。 这是我的 DRF 序列化器的序列化器:
class DynamicFieldsModelSerializer(serializers.ModelSerializer):
def __init__(self, *args, **kwargs):
super(DynamicFieldsModelSerializer, self).__init__(*args, **kwargs)
fields = self.context['request'].query_params.get('fields')
if fields:
fields = fields.split(',')
allowed = set(fields)
existing = set(self.fields.keys())
for field_name in existing - allowed:
self.fields.pop(field_name)
还有我的序列化器:
class MySerializer(serializer_mixins.DynamicFieldsModelSerializer, serializers.ModelSerializer):
# fields...
这样就达到了不包括用户在查询集的fields参数中没有提到的字段的目的。但!我们最终对获取整个字段集的数据库进行了实际查询。反过来,只需将以下代码添加到视图即可解决此问题:
class Rfs(ListAPIView):
serializer_class = MySerializer
def get_queryset(self):
qs = ...
fields = request.query_params.get('fields')
if fields:
qs = qs.only(*fields.split(','))
return qs
但是,这里填补了两个问题:
- 非 DRY 模式,因为我们必须在视图和序列化程序中重复自己
- 有时可能是查询集中的字段名称与模型的字段名称不完全对应。
那么对于这个用例,也许有一些更优雅和 Django 原生的解决方案?
【问题讨论】:
-
您是否尝试过制作动态网址,例如
path(my/own/uri/<param1:str>/<param2:str>/'...and 在你看来你可以设置你的方法get(request, param1=None, param2=None)?依赖于此,您可能会覆盖to_representation()