是否可以通过使用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"} |
----------------------------------------------------------------
因此:
----------------------------------------------------------------
| name | my_json_field |
----------------------------------------------------------------
| record_1 | {"field1": "A1", "field2": "A2", "field3": "A3"} |
----------------------------------------------------------------
----------------------------------------------------------------
| 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" } |
----------------------------------------------------------------
答案 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
的东西。