如何查询 Django 查询集中的多对多字段中是否存在实例

问题描述 投票:0回答:2

这里是简化的模型定义

class Resource(models.Model):
    name = models.CharField(max_length=100, unique=True)

class Location(models.Model):
    name = models.CharField(max_length=100, unique=True)
    resources = models.ManyToManyField(Resource)

我想知道对于一种类型的

Resource
,每个
Location
上是否存在。所以我想要的json数据就像

[
    {
        "id": 1,
        "name": "loaction_A",
        "resource": true
    }, 
    {
        "id": 2
        "name": "location_B",
        "resource": false
    },
    ...
]

我尝试了以下视图功能,但显然得到了错误的结果。

def resource_view(request, res_id):
    res = get_object_or_404(Resource, pk=res_id)
    locations = Location.objects.values('id', 'name')\
        .annotate(resource=Q(resources=res))
    return JsonResponce({'locations': list(locations)})

我知道我需要类似下面的东西(在 SQL 中)

select
    app_location.*,
    1 in (
        select resource_id
        from app_location_resources
        where location_id = app_location.id
    ) as resource
from app_location

我应该如何构建查询集?

django django-serializer
2个回答
1
投票

稍微更有效的方法可能是:

from django.db.models import Exists, OuterRef

locations = Location.objects.annotate(
    resource=Exists(
        Location.resources.through.objects.filter(
            location_id=OuterRef('pk'), resource_id=res_id
        )
    )
)

但是,我建议使用适当的序列化器,例如 Django REST 框架,也许使用 Django REST 框架:序列化器可以双向工作,例如可以以逗号分隔的值呈现数据(

.csv 
)格式。


1
投票

通过

Exists
子查询让它工作

def resource_view(request, res_id):
   res = get_object_or_404(Resource, pk=res_id)
   locations = Location.objects.values('id', 'name').annotate(
      resource=Exists(res.location_set.filter(pk=OuterRef('pk')))
   )
   return JsonResponse({'locations': list(locations)})
© www.soinside.com 2019 - 2024. All rights reserved.