我先给我的模型然后写说明。
class Entry(models.Model):
entry_text = models.TextField()
class Category(models.Model):
user = models.ForeignKey(User)
category_text = models.CharField(max_length=200)
entries = models.ManyToManyField(Entry, through='CategoryEntry')
class CategoryEntry(models.Model):
category = models.ForeignKey(Category)
entry = models.ForeignKey(Entry)
viewed = models.BooleanField(default=False)
所以我有Entry模型和Category模型,我在这里创建了中间模型CategoryEntry https://docs.djangoproject.com/en/1.7/topics/db/models/#extra-fields-on-many-to-many-relationships,因为我需要一个额外的字段"查看" (当用户第一次打开特定的Entry链接时标记为True。)
所以我创建了generic.ListView视图,其中显示了用户为自己创建的所有这些类别。我想要的是,在每个类别名称旁边显示,有多少条目以及他还没有查看过多少条目。 像:
Category Total Not_viewed
AAA 126 5
BBB 17 15
我已设法通过
显示模板中的总条目数{% for category in categories %}
{{ category.text }}
{{ category.entries.count }}
{% endfor %}
在我看来,我有get_queryset喜欢
def get_queryset(self):
categories = Category.objects.filter(user=self.request.user.id)[:]
return categories
据我了解,那么最好的方法是以某种方式添加关于在get_queryset中查看的每个类别条目的额外信息。我一直在寻找,但没有找到任何有用的东西。用select_related,prefetch_related,annotate尝试了一些东西,但没有找到正确的方法来做到这一点。 知道它不对,但尝试了类似的东西和其他一些东西。
categories = Category.objects.filter(user=self.request.user.id).select_related('categoryentry').filter(categoryentry__viewed=False).count()
categories = Category.objects.filter(user=self.request.user.id).annotate(not_viewed_count=Count('categoryentry')).filter(not_viewed_count__viewed=False)
希望你明白我想要实现的目标。
答案 0 :(得分:0)
在CategoryEntry
模型中,在类别字段中使用related_name,如下所示:
category = models.ForeignKey(Category, related_name="related_entry_categories")
现在,您可以在查询Category
模型时使用此相关名称。例如:
from itertools import chain
categories_not_viewed = Category.objects.filter(user=self.request.user.id, related_entry_categories__viewed=False).annotate(num_not_viewed=Count('related_entry_categories'))
categories_viewed = Category.objects.filter(user=self.request.user.id, related_entry_categories__viewed=True).extra(select={'num_not_viewed': 0})
categories = chain(list(categories_not_viewed), list(categories_viewed))
答案 1 :(得分:0)
最后我提出了这个解决方案:
categories = Category.objects.filter(user=self.request.user.id).extra(select = {
"num_not_viewed" : """
SELECT COUNT(*)
FROM app_categoryentry
WHERE app_categoryentry.category_id = app_category.id
AND app_categoryentry.viewed = %d """ % 0,
})
基于此资源的解决方案http://timmyomahony.com/blog/filtering-annotations-django/
如果有人有其他解决办法如何只用Django ORM获得相同的结果,我想知道。