2011-11-02 35 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>] 
相关问题