0

使用 ReviewBoard 1.6.11,它使用 Django 1.3.3。有一个 RepositoryManager 类,它有一个名为“可访问”的方法,定义如下:

class RepositoryManager(Manager):
    def accessible(self, user, visible_only=True, local_site=None):
        """Returns repositories that are accessible by the given user."""
        if user.is_superuser:
            qs = self.all()
        else:
            q = Q(public=True)

            if visible_only:
                q = q & Q(visible=True)

            if user.is_authenticated():
                q = q | (Q(users__pk=user.pk) |
                         Q(review_groups__users=user.pk))

            qs = self.filter(q).distinct()

        return qs.filter(local_site=local_site)

问题是我想用其他不与数据库交互的东西(用户的文件系统权限)过滤这个查询的结果。不过,accessible() 需要返回一个 QuerySet。否则,我只会创建一个列表并用结果中的适当项目填充它。

我对 Django 很陌生。这是一个合理的做法,还是我做错了?

4

1 回答 1

0

我可以通过像这样创建一个 QuerySet 子类来解决这个问题:

class RepositoryQuerySet(QuerySet):
    def __init__(self, *args, **kwargs):
        super(RepositoryQuerySet, self).__init__(*args, **kwargs)
        self._user_filter = None

    def _clone(self, *args, **kwargs):
        retval = super(RepositoryQuerySet, self)._clone(*args, **kwargs)
        retval._user_filter = self._user_filter
        return retval

    def filter_by_user_access(self, user):
        self._user_filter = user.username

    def iterator(self):
        for repo in super(RepositoryQuerySet, self).iterator():
            if self._user_filter is None:
                yield repo
                continue
            # ...logic for restricting access by user...
            # If user has access, just yield repo.  If not, just 'continue'

然后在 RepositoryManager.accessible 中,在调用 distinct() 之后,调用:

            qs.filter_by_user_access(user)

最后,为了让管理器使用新的查询集类,创建:

    def get_query_set(self):
        return RepositoryQuerySet(self.model, using=self.db)

在 RepositoryManager 类中。

于 2012-09-05T20:24:29.223 回答