这里是简化的模型定义
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
我应该如何构建查询集?
稍微更有效的方法可能是:
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
)格式。
通过
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)})