DjangoRestFramework:在JsonField中搜索元素并对其进行排序

时间:2019-05-08 22:38:55

标签: json django django-rest-framework

是否可以通过使用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-> field3排序DESC,我得到:
----------------------------------------------------------------
| 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" }                |
----------------------------------------------------------------

1 个答案:

答案 0 :(得分:1)

我还没有测试过,但是希望可以为您指明正确的方向。

第一个问题是Django可以做什么-Django可以对JSONField上的任意键进行过滤和排序吗?要进行过滤,请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的东西。