在Django中是否有一种方法可以在具有外键的模型上使用FOO_set,该外键引用相同模型类型的对象?

时间:2011-11-02 14:33:26

标签: django django-models django-queryset

我有一个这样的模型:

    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有关 - 因为解决这个问题可以解决问题。这样做的正确方法是什么?

2 个答案:

答案 0 :(得分:2)

答案 1 :(得分:0)

这不能解决您的具体问题(切片查询集),但您帖子的标题表明您不了解related_name的{​​{1}}属性。

ForeignKey

使用相关名称可以更自然地进行查询:

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