sql - Django ORM左连接到同一张表
问题描述
我在 django 项目中有一个自定义权限系统,可以将任何用户链接到任何特定模型实例以授予对该对象的权限。它比这更复杂,但归结为:
class Permission(models.Model):
user = models.ForeignKey(User)
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
object_id = models.PositiveIntegerField()
content_object = GenericForeignKey('content_type', 'object_id')
我想查询任何用户的所有权限,这些权限链接到特定用户已被授予权限的相同 content_object(s)。换句话说,有问题的用户想要查看还有谁对他们所做的任何相同对象拥有权限。
在 SQL 中,以下方法可以解决问题:
SELECT
perm1.*
FROM app_permission perm1
LEFT JOIN app_permission perm2
ON perm2.user_id = 12345
AND perm1.content_type_id = perm2.content_type_id
AND perm1.object_id = perm2.object_id
WHERE perm2.id IS NOT NULL;
是否有可能在 django ORM 中实现这一点?
解决方案
您可以使用Exists
子查询 [Django-doc],这可能是您打算做的,所以:
from django.db.models import Exists, OuterRef
Permission.objects.filter(
Exists(Permission.objects.filter(
user_id=12345, content_type_id=OuterRef('content_type_id'), object_id=OuterRef('object_id')
))
)
另一种选择可能是对模型使用“一二技巧”ContentType
并使用:
from django.db.models import F
Permission.objects.filter(
content_type__permission__user=12345,
content_type__permission__id__isnull=False,
content_type__permission__object_id=F('object_id')
)