2012-09-05 55 views
0

使用ReviewBoard 1.6.11,它使用Django 1.3.3。 有一個RepositoryManager類,有一個名爲「訪問」的方法,定義爲這樣:過濾由非數據庫操作設置的django查詢

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相當陌生。這是一件合理的事情嗎?或者我會說這一切都是錯誤的?

回答

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,調用不同的()之後,調用:

  qs.filter_by_user_access(user) 

最後,爲經理使用新的查詢集類,創建:

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

in RepositoryMana ger類。