2011-11-02 32 views
0

我有這樣一個模型:在Django中,有沒有一種方法可以在引用同一模型類型的對象的外鍵的模型上使用FOO_set?

class Video(models.Model): 
     views = models.ManyToManyField(User, null=True, related_name='views') 
     parent = models.ForeignKey('self', null=True) 

     def __unicode__(self): 
     return self.title 

     def _get_views_count(self): 
     return self.views.count() 

     def _get_comments_count(self): 
     return self.comment_set.all().count() 

     def _get_playlists(self): 
     return self.playlist_set.all() 

     views_count = property(_get_views_count) 
     comments_count = property(_get_comments_count) 
     playlists = property(_get_playlists) 

     most_viewed_objects = MostViewedVideoManager() 
     objects = models.Manager() 



class MostViewedVideoManager(models.Manager): 
     def get_query_set(self): 
     return super(MostViewedProjectManager, self).get_query_set().annotate(lovers=Count('views')).order_by('viewers')[:20] 

而且我想要得到的一組具有給定父影片的。我想我可能只是做這樣的事情:

v = Video.objects.get(id=3) 
v.video_set.all() 

但是它拋出這個錯誤:

AssertionError: Cannot filter a query once a slice has been taken. 

    (full trace) 
    /usr/local/lib/python2.7/dist-packages/django/db/models/manager.pyc in all(self) 
    115 
    116  def all(self): 
--> 117   return self.get_query_set() 
    118 
    119  def count(self): 

/usr/local/lib/python2.7/dist-packages/django/db/models/fields/related.pyc in get_query_set(self) 
    421    def get_query_set(self): 
    422     db = self._db or router.db_for_read(rel_model, instance=instance) 
--> 423     return superclass.get_query_set(self).using(db).filter(**(self.core_filters)) 
    424 
    425    def add(self, *objs): 

/usr/local/lib/python2.7/dist-packages/django/db/models/query.pyc in filter(self, *args, **kwargs) 
    548   set. 
    549   """ 
--> 550   return self._filter_or_exclude(False, *args, **kwargs) 
    551 
    552  def exclude(self, *args, **kwargs): 

/usr/local/lib/python2.7/dist-packages/django/db/models/query.pyc in _filter_or_exclude(self, negate, *args, **kwargs) 
    560   if args or kwargs: 
    561    assert self.query.can_filter(), \ 
--> 562      "Cannot filter a query once a slice has been taken." 
    563 
    564   clone = self._clone() 

我相信這是關係到MostViewedManager - 因爲服用了這一點解決了問題。什麼是正確的方法來做到這一點?

+0

該錯誤不從該代碼的到來。請發佈完整的代碼和真正的回溯。另外,請接受一些答案。 –

+0

謝謝 - 你是對的 - 它看起來像錯誤是關係到經理類MostViewedVideoManager ....但我不知道爲什麼...我已經添加了完整的跟蹤和更多的代碼。 –

+0

你在某處嘗試過濾從MostViewedVideoManager返回的查詢集...... –

回答

2

如錯誤消息所示,您正試圖過濾已被切片的查詢集。

不要從經理的get_query_set方法返回切片查詢集。可以返回未經處理的內容,也可以創建一個單獨的方法返回切片版本。

+0

嗯有道理 - 謝謝! –

0

這並不能解決您的特定問題(切片查詢集),但是您的帖子的標題表明您不知道 ForeignKey的屬性。

class Video(models.Model): 
    views = models.ManyToManyField(User, null=True, related_name='views') 
    parent = models.ForeignKey('self', null=True, related_name='children') 

使用相關的名字可以讓你更自然地查詢:

>>> video = Video.objects.get(id=1) 
<Video: 1> 
>>> video.children.all() 
[<Video: 2>, <Video: 3>, <Video: 4>] 
>>> gte2_lovers = Video.objects.annotate(lovers=count('views')).filter(lovers__gte=2) 
>>> Video.objects.filter(children__in=gte2_lovers) 
[<Video: 1>, <Video: 4>] 
相關問題