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つのSELECTが表示されます(権限、役割、およびroles__permissions)

どうやってするの?

4

2 に答える 2

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 に答える
0

この質問を読んでください: A left outer reverse select_related in Django?

当時、Django にprefetch_related(){% regroup %}.

多対多の場合、最下位のテーブルは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 に答える