如何在 django rest 框架中的 postgres JSONField 上应用过滤器?
Posted
技术标签:
【中文标题】如何在 django rest 框架中的 postgres JSONField 上应用过滤器?【英文标题】:how to apply filters on a posgres JSONField in django rest framework? 【发布时间】:2020-03-07 11:37:16 【问题描述】:我有一个类似的模型:
# segment/models.py
from django.db import models
from django.contrib.postgres.fields import JSONField
class Segment(models.Model):
name = models.CharField(max_length=100)
# docs: https://docs.djangoproject.com/en/2.2/ref/contrib/postgres/fields/#jsonfield
data = JSONField('data', 'data')
在字段数据我存储类似于此的JSON数据
"length": 123.45
"difficulty":
"avg": "easy"
"max": "advanced"
我希望能够查询如下数据:
api/segments/?data__difficulty__avg=easy过滤所有记录
data.difficulty.avg="easy".为此,我设置了序列化程序:
# api/serializers.py
from rest_framework import serializers
class SegmentSerializer(serializers.ModelSerializer):
class Meta:
model = Segment
fields = ['id', 'name', 'data']
视图如下所示:
# api/views.py
from django_filters.rest_framework import DjangoFilterBackend
from .serializers import SegmentSerializer
from segment.models import Segment
class SegmentViewSet(viewsets.ReadOnlyModelViewSet):
queryset = Segment.objects.all()
serializer_class = SegmentSerializer
filter_backends = [DjangoFilterBackend]
filterset_fields = ['id', 'name', 'data']
当我打电话时
api/segments我收到以下错误
AssertionError at /api/segments/
AutoFilterSet resolved field 'data' with 'exact' lookup to an unrecognized field type JSONField. Try adding an override to 'Meta.filter_overrides'. See: https://django-filter.readthedocs.io/en/master/ref/filterset.html#customise-filter-generation-with-filter-overrides
Request Method: GET
Request URL: http://localhost:8000/api/segments/
Django Version: 2.2.7
Python Executable: /Users/udos/.virtualenvs/ts/bin/python
Python Version: 3.6.4
.
.
.
我尝试将 data = serializers.JSONField() 添加到序列化程序中:
# api/serializers.py
from rest_framework import serializers
class SegmentSerializer(serializers.ModelSerializer):
data = serializers.JSONField()
class Meta:
model = Segment
fields = ['id', 'name', 'data']
但错误仍然存在。所以我没有正确应用它:|
这是如何正确完成的?
【问题讨论】:
【参考方案1】:我正在尝试同样的事情并找到了SearchFilter
。
所以对你来说,它会是这样的:
# api/views.py
from rest_framework import filters
from .serializers import SegmentSerializer
from segment.models import Segment
class SegmentViewSet(viewsets.ReadOnlyModelViewSet):
queryset = Segment.objects.all()
serializer_class = SegmentSerializer
filterset_fields = ['id', 'name']
filter_backends = [filters.SearchFilter]
search_fields = ['data__difficulty__avg']
【讨论】:
以上是关于如何在 django rest 框架中的 postgres JSONField 上应用过滤器?的主要内容,如果未能解决你的问题,请参考以下文章
Django REST 框架:使用 URL 中的 ID 发布到 URL
Django REST框架:POST请求:仅在数据不存在时如何保存数据