如何使用json_field查询复杂的查询

时间:2019-10-31 11:02:44

标签: python django django-rest-framework django-views

在我的django应用中,我具有以下模型层次结构:

Project
BuildingCollection (belongs to Project)
Building (belongs to BuildingCollection)
SpecificValue (belongs to Building)

SpecificValue模型具有一个JSON字段,其中包含许多键和值,例如{1:value2, 2: value2, 3:value3.....}。 SpecificValue模型还具有一个选择字段,其中包含3种类型的选择。

我正在尝试通过看起来像这样的URL查询以下内容: path('blbla/<str:project>/<str:type>/<str:key>/', blbla.as_view())

我想用伪代码查询这个:

  

请给我在URL中传递的项目的最新BuildingCollection的所有建筑物。然后给我这些建筑物的所有SpecificValues,但只给那些在URL中传递类型的建筑物。最后,从所有这些SpecificValues中仅给出JSON字段中指定键的值。

然后我想将其写成字典,写着:{"Building1" : valueofJSONField, "Building2" : valueofJSONField }

我希望我的意思清楚。我正在尝试以下操作(覆盖REST APIView的get方法)

class MyClass(APIView):

    def get(self, request,  **kwargs):
        project = kwargs.get('project')
        type = kwargs.get('type')
        key = kwargs.get('key')

        building_group_most_recent = BuildingCollection.objects.filter(
            project__project_name=project).order_by('-creation_date').first() #I get mostrecent

        buildings = building_collection_most_recent.buildings.all() ##all buildings
        specific_value = buildings.specific_value.all() ##ERROR HERE ==> buildings has no specific_value_set

我认为发生此错误是因为我的建筑物很多。我可以循环播放并推送到列表,但随后它们与建筑物断开连接。

我也尝试了另一种方法:

building_by_spec_values = SpecificValues.objects.filter(
            building__buildingcollection__project=project,
            type__exact=type,
            value__has_key=key). \
            order_by('-timestamp'
                     )

这里的问题是我只需要传递一个建筑实例,否则会收到错误The QuerySet value for an exact lookup must be limited to one result

我知道我可以使用__has_key.从JSON字段中获取值,如Django文档中所述,但是直到JSON字段的方式给我带来了麻烦。无论哪种方式,我都无法解决所有问题。

任何人都可以帮助我,或者对我如何前进有一些想法?非常感谢,非常感谢。

这是我的特定型号:


class SpecificValue(models.Model):
    OPTION1 = 'option1'
    OPTION2 = 'option2'
    OPTION3 = 'option3'
    CHOICES = [
        (OPTION1, 'op1'),
        (OPTION2, 'op2'),
        (OPTION3, 'op3'),
    ]

    building = models.ForeignKey(Building, on_delete=models.CASCADE, null=True,
                                 blank=True, related_name="specific_value")
    type = models.CharField(max_length=4, choices=HEAT_COOL_CHOICES)
    values_and_keys = JSONField()
    timestamp = models.DateTimeField(null=True, blank=True)

0 个答案:

没有答案