Django ORM:使用链接 table 连接两个 table
Django ORM: Join two tables using a linked table
我想在 class Profile
中集成一个功能 has_permission(self, permission_name)
。
为此,我想做一个 ORM 语句,其中 returns 权限名称列表。
数据模型为:
- 1 用户有 1 个人资料(扩展 Django 的用户模型)
- 每个 Profile 都分配给一个 ProfileGroup。
但是,不同的 Profiles 可以属于同一个 ProfileGroup.
- 每个 ProfileGroup 可以有一个或多个 ProfilePermissions。组可以具有相同的 ProfilePermissions 子集。 Link-Table GroupPermissions 使用两个
ForeignKeys
而不是 ManyToMany
关系来处理此问题。
我的 models.py
看起来像这样:
class ProfileGroup(models.Model):
name = models.CharField(max_length=64)
class ProfilePermission(models.Model):
name = models.CharField(max_length=64)
class GroupPermissions(models.Model):
group = models.ForeignKey(ProfileGroup, on_delete=models.RESTRICT)
permission = models.ForeignKey(ProfilePermission, on_delete=models.RESTRICT)
class Meta:
constraints = [
models.UniqueConstraint(fields=['group', 'permission'], name='Unique')
]
def __str__(self):
return f'Group "{self.group.name}" has permission "{self.permission.name}"'
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
group = models.ForeignKey(ProfileGroup, on_delete=models.RESTRICT)
def __str__(self):
return f'Profile of {self.user.username}'
def has_permission(self, permission_name):
return True
函数 has_permission
(在 Profile
class 中)应该检查权限 permission
是否包含在权限列表中。我试过
list_of_permissions = GroupPermissions.objects.filter(group=self.group)
但是这个returns列表ProfilePermission
。我想要的是权限名称列表 (permission.name
).
所以我必须加入两个 Tables GroupPermissions
和 ProfilePermission
。我发现了 prefetch_related
和 select_related
但这并不像我想要的那样工作。
直接回答你的问题,
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
group = models.ForeignKey(ProfileGroup, on_delete=models.RESTRICT)
def __str__(self):
return f'Profile of {self.user.username}'
def has_permission(self, permission_name):
return GroupPermissions.objects.filter(group=self.group, permission__name=permission_name).exists()
但是...我对您的建议是不要试图重新发明轮子。 django.contib.auth 已有组和权限,只需使用它们;-)
我想在 class Profile
中集成一个功能 has_permission(self, permission_name)
。
为此,我想做一个 ORM 语句,其中 returns 权限名称列表。
数据模型为:
- 1 用户有 1 个人资料(扩展 Django 的用户模型)
- 每个 Profile 都分配给一个 ProfileGroup。 但是,不同的 Profiles 可以属于同一个 ProfileGroup.
- 每个 ProfileGroup 可以有一个或多个 ProfilePermissions。组可以具有相同的 ProfilePermissions 子集。 Link-Table GroupPermissions 使用两个
ForeignKeys
而不是ManyToMany
关系来处理此问题。
我的 models.py
看起来像这样:
class ProfileGroup(models.Model):
name = models.CharField(max_length=64)
class ProfilePermission(models.Model):
name = models.CharField(max_length=64)
class GroupPermissions(models.Model):
group = models.ForeignKey(ProfileGroup, on_delete=models.RESTRICT)
permission = models.ForeignKey(ProfilePermission, on_delete=models.RESTRICT)
class Meta:
constraints = [
models.UniqueConstraint(fields=['group', 'permission'], name='Unique')
]
def __str__(self):
return f'Group "{self.group.name}" has permission "{self.permission.name}"'
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
group = models.ForeignKey(ProfileGroup, on_delete=models.RESTRICT)
def __str__(self):
return f'Profile of {self.user.username}'
def has_permission(self, permission_name):
return True
函数 has_permission
(在 Profile
class 中)应该检查权限 permission
是否包含在权限列表中。我试过
list_of_permissions = GroupPermissions.objects.filter(group=self.group)
但是这个returns列表ProfilePermission
。我想要的是权限名称列表 (permission.name
).
所以我必须加入两个 Tables GroupPermissions
和 ProfilePermission
。我发现了 prefetch_related
和 select_related
但这并不像我想要的那样工作。
直接回答你的问题,
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
group = models.ForeignKey(ProfileGroup, on_delete=models.RESTRICT)
def __str__(self):
return f'Profile of {self.user.username}'
def has_permission(self, permission_name):
return GroupPermissions.objects.filter(group=self.group, permission__name=permission_name).exists()
但是...我对您的建议是不要试图重新发明轮子。 django.contib.auth 已有组和权限,只需使用它们;-)