Django Rest Framework基于JSONField嵌套对象进行过滤

问题描述 投票:-1回答:2

我正在使用Python(3),Django(1.11)和DRF开发一个项目,我必须在json对象字段的基础上过滤数据,该字段在db模型中保存为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

它应该通过props ID返回MyModel记录,并且应该能够通过MyModel objects的GET请求返回props ID所在的所有/mymodel/props/<ID>的JSON数组。如果请求的props不存在,则HTTP响应代码应为404,否则,响应代码应为200. JSON数组应按MyModel ID按升序排序。

当我向此视图发送请求时,它会返回错误:

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过滤对象?

请帮帮我!提前致谢!

python django django-rest-framework django-filter drf-queryset
2个回答
1
投票

您正在寻找的功能是可能的,不幸的是它不是那么简单。据我所知,它不受jsonfield包支持,但你必须使用Postgres as your database backend and use its internal JSONField。我想你可以选择以下之一:

  • 切换到qazxsw poi并在所有环境中使用Postgres作为db后端(然后支持此类查找)
  • 使数据遵循特定模式并将JSONField更改为单独的模型和表
  • 使用混合存储解决方案和JSON文档的专用解决方案
  • 提取需要查询到模型的字段 - 启用查询,但将非结构化数据保留在JSONField中。
django.contrib.postgres.fields.JSONField

然后手动或在模型的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() 中设置id值:

save()

0
投票

你应该用

def save(self, *args, **kwargs):
    self.repo_id = self.repo.get("id")
    self.props_id = self.props.get("id")
    return super().save(*args, **kwargs)

代替

from django.contrib.postgres.fields import JSONField

之后,我认为一切都应该正常

© www.soinside.com 2019 - 2024. All rights reserved.