基于 JSONField 嵌套对象的 Django Rest Framework 过滤器
Django Rest Framework filter on the base of JSONField nested objects
我正在使用 Python(3)、Django(1.11) 和 DRF 开发一个项目,我必须在 json
对象字段的基础上过滤数据在数据库模型中保存为 JSONFIELD
。
这是我尝试过的:
# model.py
from django.db import models
import jsonfield
class MyModel(models.Model):
id = models.CharField(primary_key=True, max_length=255)
type = models.CharField(max_length=255)
props = jsonfield.JSONField()
repo = jsonfield.JSONField()
created_at = models.DateTimeField()
# serializers.py
class MyModelSerializer(serializers.ModelSerializer):
props = serializers.JSONField()
repo = serializers.JSONField()
class Meta:
model = EventModel
fields = "__all__"
# JSON object
{
"id":4633249595,
"type":"PushEvent",
"props":{
"id":4276597,
"login":"iholloway",
"avatar_url":"https://avatars.com/4276597"
},
"repo":{
"id":269910,
"name":"iholloway/aperiam-consectetur",
"url":"https://github.com/iholloway/aperiam-consectetur"
},
"created_at":"2016-04-18 00:13:31"
}
# views.py
class PropsEvents(generics.RetrieveAPIView):
serializer_class = MyModelSerializer
def get_object(self):
print(self.request.parser_context['kwargs']['id'])
queryset = MyModel.objects.filter(data__props__id=self.request.parser_context['kwargs']['id'])
obj = get_object_or_404(queryset)
return obj
It should return the MyModel records by props ID
and should be able to
return the JSON array of all the MyModel objects
where the props ID
by
the GET request at /mymodel/props/<ID>
. If the requested props
does not
exist then HTTP response code should be 404, otherwise, the response
code should be 200. The JSON array should be sorted in ascending order
by MyModel ID.
当我向这个视图发送请求时,它 returns 一个错误:
> django.core.exceptions.FieldError: Unsupported lookup 'id' for JSONField or join on the field not permitted.
> [18/Feb/2019 10:37:39] "GET /events/actors/2790311/ HTTP/1.1" 500 16210
那么,如何根据 id of props
筛选对象?
请帮帮我!
提前致谢!
你应该使用
from django.contrib.postgres.fields import JSONField
而不是
import jsonfield
然后我认为一切都应该正常工作
您正在寻找的功能是可能的,不幸的是它不是那么简单。据我所知,jsonfield
包不支持它,但您必须使用 Postgres as your database backend and use its internal JSONField。我想你可以选择以下其中一项:
- 切换到
django.contrib.postgres.fields.JSONField
并在所有环境中使用 Postgres 作为您的数据库后端(然后支持此类查找)
- 使数据遵循一定的模式并将 JSON 字段更改为单独的模型并且 table
- 使用混合存储解决方案和 JSON 个文档的专用解决方案
- 将您需要查询的字段提取到您的模型中 - 启用查询,但将非结构化数据保留在 JSON 字段中。
class MyModel(models.Model):
id = models.CharField(primary_key=True, max_length=255)
type = models.CharField(max_length=255)
props = jsonfield.JSONField()
props_id = models.IntegerField(null=True)
repo = jsonfield.JSONField()
repo_id = models.IntegerField(null=True)
created_at = models.DateTimeField()
然后手动或在模型的 save()
中设置 id 值:
def save(self, *args, **kwargs):
self.repo_id = self.repo.get("id")
self.props_id = self.props.get("id")
return super().save(*args, **kwargs)
我正在使用 Python(3)、Django(1.11) 和 DRF 开发一个项目,我必须在 json
对象字段的基础上过滤数据在数据库模型中保存为 JSONFIELD
。
这是我尝试过的:
# model.py
from django.db import models
import jsonfield
class MyModel(models.Model):
id = models.CharField(primary_key=True, max_length=255)
type = models.CharField(max_length=255)
props = jsonfield.JSONField()
repo = jsonfield.JSONField()
created_at = models.DateTimeField()
# serializers.py
class MyModelSerializer(serializers.ModelSerializer):
props = serializers.JSONField()
repo = serializers.JSONField()
class Meta:
model = EventModel
fields = "__all__"
# JSON object
{
"id":4633249595,
"type":"PushEvent",
"props":{
"id":4276597,
"login":"iholloway",
"avatar_url":"https://avatars.com/4276597"
},
"repo":{
"id":269910,
"name":"iholloway/aperiam-consectetur",
"url":"https://github.com/iholloway/aperiam-consectetur"
},
"created_at":"2016-04-18 00:13:31"
}
# views.py
class PropsEvents(generics.RetrieveAPIView):
serializer_class = MyModelSerializer
def get_object(self):
print(self.request.parser_context['kwargs']['id'])
queryset = MyModel.objects.filter(data__props__id=self.request.parser_context['kwargs']['id'])
obj = get_object_or_404(queryset)
return obj
It should return the MyModel records by
props ID
and should be able to return the JSON array of all theMyModel objects
where theprops ID
by the GET request at/mymodel/props/<ID>
. If the requestedprops
does not exist then HTTP response code should be 404, otherwise, the response code should be 200. The JSON array should be sorted in ascending order by MyModel ID.
当我向这个视图发送请求时,它 returns 一个错误:
> django.core.exceptions.FieldError: Unsupported lookup 'id' for JSONField or join on the field not permitted.
> [18/Feb/2019 10:37:39] "GET /events/actors/2790311/ HTTP/1.1" 500 16210
那么,如何根据 id of props
筛选对象?
请帮帮我! 提前致谢!
你应该使用
from django.contrib.postgres.fields import JSONField
而不是
import jsonfield
然后我认为一切都应该正常工作
您正在寻找的功能是可能的,不幸的是它不是那么简单。据我所知,jsonfield
包不支持它,但您必须使用 Postgres as your database backend and use its internal JSONField。我想你可以选择以下其中一项:
- 切换到
django.contrib.postgres.fields.JSONField
并在所有环境中使用 Postgres 作为您的数据库后端(然后支持此类查找) - 使数据遵循一定的模式并将 JSON 字段更改为单独的模型并且 table
- 使用混合存储解决方案和 JSON 个文档的专用解决方案
- 将您需要查询的字段提取到您的模型中 - 启用查询,但将非结构化数据保留在 JSON 字段中。
class MyModel(models.Model):
id = models.CharField(primary_key=True, max_length=255)
type = models.CharField(max_length=255)
props = jsonfield.JSONField()
props_id = models.IntegerField(null=True)
repo = jsonfield.JSONField()
repo_id = models.IntegerField(null=True)
created_at = models.DateTimeField()
然后手动或在模型的 save()
中设置 id 值:
def save(self, *args, **kwargs):
self.repo_id = self.repo.get("id")
self.props_id = self.props.get("id")
return super().save(*args, **kwargs)