在Django中,有没有一种方法可以在一个外键指向相同模型类型对象的模型上使用FOO_集?
我有一个这样的模型:在Django中,有没有一种方法可以在一个外键指向相同模型类型对象的模型上使用FOO_集?,django,django-models,django-queryset,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_co
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()
我想得到一组有特定父母的视频。我想我可以这样做:
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()
我相信这与大多数虚拟经理有关,因为去掉它可以解决问题。正确的方法是什么 正如错误消息所说,您正在尝试筛选已切片的查询集
不要从管理器的
get\u query\u set
方法返回切片查询集。可以不经许可返回它,也可以创建一个单独的方法返回切片版本。这并不能解决您的特定问题(切片查询集),但您的文章标题表明您不知道ForeignKey
的相关\u name
属性
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>]
>video=video.objects.get(id=1)
>>>video.children.all()
[, ]
>>>gte2_lovers=Video.objects.annotate(lovers=count('views')).filter(lovers_gte=2)
>>>Video.objects.filter(children\uu in=gte2\u)
[, ]
该错误不是来自该代码。请发布完整的代码和真实的回溯。加上,请接受一些答案。谢谢-你是对的-似乎错误与管理器类MostViewedVideoManager有关…但我不确定为什么…我添加了完整跟踪和更多代码。你正在尝试筛选从MostViewedVideoManager返回的查询集
…好的-我发现在我的模型解决了这个问题…虽然我不知道为什么。ie.objects=models.Manger()在大多数被查看对象之前\u objects=MostViewedVideoManager()列出的第一个管理器将成为默认管理器。在您的情况下,返回切片查询集的是您的自定义管理器。当你切换它们时,默认值变成了标准管理器,它不会分割查询集。啊,这很有意义-谢谢!