0

我有这些模型:

class Permission(models.Model):

    name = models.CharField(u'Name', max_length=100)
    codename = models.CharField(u'Code name', max_length=100)

class Role(models.Model):

    name = models.CharField(u'Name', max_length=80)
    organization = models.ForeignKey(Organization)
    permissions = models.ManyToManyField(Permission, blank=True)

class UserProfileManager(models.Manager):

    def get_query_set(self):
        return super(UserProfileManager, self).get_query_set().select_related(
            'user', 'organization'
        )

class UserProfile(models.Model):

    user = models.OneToOneField(User)

    organization = models.ForeignKey(Organization, blank=True)
    roles = models.ManyToManyField(Role, blank=True)
    permissions = models.ManyToManyField(Permission, blank=True)

    objects = UserProfileManager()

我想读取最多 2 个 SELECTS 的所有用户权限('permissions' 和 'roles__permissions')。

如果我尝试添加prefetch_related('permissions', 'roles__permissions')到 UserProfileManager 我得到 3 个选择(用于权限、角色和角色__权限)

怎么做?

4

2 回答 2

0

阅读这个问题:A left outer reverse select_related in Django?

当时,Django 没有prefetch_related(),所以我通过查询最孩子的模型并重新组合结果来解决它,或者使用{% regroup %}模板标签,或者在视图中,使用 dicts。

在多对多的情况下,最子级的表是through

# one way of optimizing: building a dict accessable by id
# beware to do this in really large tables
permissions = dict([(p.id, p) for p in Permission.objects.all()])

permission_roles = Role.permissions.through.select_related('role').all()
for permission_role in permission_roles:
    # permission_role is an object that associates a role with a permission
    # note that we haven't selected "permission", but permission_id is available:
    role = permission_role.role
    permission = permissions[permission_role.permission_id]
于 2012-12-20T13:19:41.773 回答
0

这些是我的一些辅助功能:

class UserProfile(models.Model):

    def get_permissions_user(self):
        if not hasattr(self, '_perm_user_cache'):
            perms = self.permissions.select_related()
            self._perm_user_cache = set([u'%s' % (p.codename) for p in perms])

        return self._perm_user_cache

    def get_permissions_group(self):
        if not hasattr(self, '_perm_group_cache'):
            perms = Permission.objects.filter(role__userprofile = self)
            self._perm_group_cache = set([u'%s' % (p.codename) for p in perms])

        return self._perm_group_cache

    def get_permissions(self):
        if not hasattr(self, '_perm_cache'):
            self._perm_cache = set()
            self._perm_cache.update(self.get_permissions_user())
            self._perm_cache.update(self.get_permissions_group())

        return self._perm_cache
于 2012-12-19T16:55:08.620 回答