【问题标题】:Design pattern for DRY approach to dynamic serializer fields动态序列化器字段的 DRY 方法的设计模式
【发布时间】: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()

标签: django-rest-framework


【解决方案1】:

我正在使用drf_queryfields

根据您的query_params,您的视图将被修改

获取http://127.0.0.1:8000/snippets/

[
  {
    "id": 1,
    "title": "",
    "code": "foo = \"bar\"\n",
    "linenos": false,
    "language": "python",
    "style": "friendly"
  },
  {
    "id": 2,
    "title": "",
    "code": "print \"hello, world\"\n",
    "linenos": false,
    "language": "python",
    "style": "friendly"
  }
]

获取http://127.0.0.1:8000/snippets/?fields=id,code

[
  {
    "id": 1,
    "code": "foo = \"bar\"\n",
  },
  {
    "id": 2,
    "code": "print \"hello, world\"\n",
  }
]

我希望这就是您想要实现的目标。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多