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中实现这个吗?

您可以使用Existssubquery [Django-doc],这可能是你想要做的,所以:

from django.db.models importExists, 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 importF
Permission.objects.filter(
content_type__permission__user=12345,
content_type__permission__id__isnull=False,
content_type__permission__object_id=F('object_id')
)