【问题标题】:DjangoRestFramework: search and sort a element inside a JsonFieldDjango Rest Framework:在 JsonField 中搜索和排序元素
【发布时间】:2019-09-26 17:32:02
【问题描述】:

是否可以通过使用 django_rest_framework 创建自定义方法以某种方式搜索/排序 JsonField 中的字段?

----------------------------------------------------------------
| name      |               my_json_field                      |
---------------------------------------------------------------- 
| record_1  | {"field1": "A1", "field2": "A2", "field3": "A3"} | 
----------------------------------------------------------------
| record_2  | {"field1": "B2", "field2": "B1" }                |
----------------------------------------------------------------
| record_3  | {"field1": "C3", "field2": "C2", "field3": "C1"} |
----------------------------------------------------------------

这样:

  • 如果按 my_json_field 过滤 -> field1 = "A1" 我得到:
----------------------------------------------------------------
| name      |               my_json_field                      |
---------------------------------------------------------------- 
| record_1  | {"field1": "A1", "field2": "A2", "field3": "A3"} | 
----------------------------------------------------------------
  • 如果按 my_json_field 排序 DESC -> field3 我得到:
----------------------------------------------------------------
| name      |               my_json_field                      |
----------------------------------------------------------------
| record_3  | {"field1": "C3", "field2": "C2", "field3": "C1"} |
---------------------------------------------------------------- 
| record_1  | {"field1": "A1", "field2": "A2", "field3": "A3"} | 
----------------------------------------------------------------
| record_2  | {"field1": "B2", "field2": "B1" }                |
----------------------------------------------------------------

【问题讨论】:

    标签: json django django-rest-framework


    【解决方案1】:

    我还没有对此进行测试,但希望可以为您指明正确的方向。

    第一个问题是 Django 可以做什么 - Django 可以通过JSONFields 上的任意键转换进行过滤和排序吗?对于过滤,absolutely。对于排序,不是直接的。通常,您不能按转换排序,但是您可以将这些转换注释到查询集,然后对注释进行过滤。这个answer 提供了一个如何使用JSONField 执行此操作的示例。

    第二个问题是 DRF 能做什么。查看代码,SearchFilter 并不严重依赖模型元,因此在search_fields 中使用键转换应该没问题。如果没有,您可以尝试使用注释。与 Django 类似,OrderingFilter 不支持转换,但它支持注释。把这些放在一起,类似下面的东西应该可以工作:

    from rest_framework import viewsets, filters
    from django.contrib.postgres.fields.jsonb import KeyTextTransform
    from my_app.models import MyModel
    
    class MyModelViewSet(viewsets.ModelViewSet):
        queryset = MyModel.objects \
            .annotate(field1=KeyTextTransform('my_json_field', 'field1') \
            .annotate(field2=KeyTextTransform('my_json_field', 'field2') \
            .annotate(field3=KeyTextTransform('my_json_field', 'field3')
    
        filter_backends = [filters.SearchFilter, filters.OrderingFilter]
        search_fields = ['field1', 'field2', 'field3']
        ordering_fields = ['field1', 'field2', 'field3']
    

    请注意,您不能仅通过单个字段显式搜索,而是搜索所有搜索字段。为此,您需要使用 django-filter 之类的内容。

    【讨论】:

    • 非常感谢我能够做我想做的事!今天之前我不知道注释
    • 从 Django 3 开始使用 django.db.models.fields.json.KeyTextTransform
    猜你喜欢
    • 1970-01-01
    • 2015-10-06
    • 2016-02-12
    • 2015-08-02
    • 1970-01-01
    • 2014-04-21
    • 2023-01-27
    相关资源
    最近更新 更多