在我的博客中,帖子根据类别进行了划分。我从类别列表中排除了名为“未分类”的类别,现在我想排除空类别。
在context_processor中,我可以正常运行以下查询:
MyCategory.objects.exclude(category_name="Uncategorized")
我尝试过这样的查询:
def myblog_menu(request):
myblog_menu_link = MyCategory.objects.exclude(category_name="Uncategorized").filter(category_name__category_set__isnull=True)
return {
'myblog_menu_link': myblog_menu_link,
}
但是我看到这个错误:
CharField不支持的查找'category_set'或在字段上加入 不允许。
我该如何解决?
models.py
class MyCategory(models.Mode):
category_name = models.CharField(...)
.
.
:
class BlogPost(models.Mode):
title = models.CharField(...)
category = models.ForeignKey(MyCategory, related_name="category_set", ....)
.
.
:
答案 0 :(得分:1)
您可以排除以下内容为空的类别:
MyCategory.objects.exclude(
category_name='Uncategorized'
).filter(
category_set__isnull=False
).distinct()
这将因此生成如下查询:
SELECT DISTINCT mycategory.*
FROM mycategory
INNER JOIN blogpost ON mycategory.id = blogpost.category_id
WHERE NOT (mycategory.category_name = 'Uncategorized')
AND blogpost.id IS NOT NULL
因此,我们在这里指定如果我们用LEFT OUTER JOIN
制作一个BlogPost
,那应该是空的。这里的查询是INNER JOIN
,这是一种优化,因为如果我们过滤掉可为空的变量,那么很显然我们不必首先生成那些空变量。
话虽这么说,我强烈建议您将related_name
外键的category
更改为blogpost_set
,或直接保留。 related_name
是对象的名称,Category
没有category_set
,它有一组blogposts
:
class BlogPost(models.Mode):
title = models.CharField(...)
category = models.ForeignKey(MyCategory, related_name='blogpost_set', ....)
在这种情况下,查询为:
MyCategory.objects.exclude(
category_name='Uncategorized'
).filter(
blogpost_set__isnull=False
).distinct()