基于JSONField嵌套对象的Django Rest框架过滤器

时间:2019-02-18 10:50:33

标签: python django django-rest-framework django-filter drf-queryset

我正在使用Python(3),Django(1.11)和DRF开发项目,其中我必须根据保存为{{1}的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 返回MyModel记录,并且应该能够   返回所有props ID的JSON数组,其中MyModel objects由   props ID处的GET请求。如果请求的/mymodel/props/<ID>没有   存在,则HTTP响应代码应为404,否则,响应   代码应为200。JSON数组应按升序排序   通过MyModel ID。

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

props

那么,如何基于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 过滤对象?

请帮帮我! 预先感谢!

2 个答案:

答案 0 :(得分:1)

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

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

然后手动或在模型的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)

答案 1 :(得分:0)

您应该使用

from django.contrib.postgres.fields import JSONField

代替

import jsonfield

在那之后,我认为一切都应该正常工作