也许是一个简单的问题,但我刚刚开始使用Django几年的PHP经验: - )
问题:我们有一对模型 - “类别”和“发布”。 “类别”是帖子类别的嵌套集树,“帖子”是带有ForeignKey字段的博客帖子的简单列表,链接到类别模型。这是一个例子:
class Categories(NS_Node):
title = models.CharField(max_length = 150)
slug = models.SlugField(unique = True)
class Post(models.Model):
title = models.CharField(max_length = 150)
slug = models.SlugField(unique = True)
text = models.TextField()
category = models.ForeignKey(Categories)
NS_Node - 来自treebeard库的类,实现嵌套集数据模型。
用户可以通过访问带有“/ books / sci-fi /”等网址的页面查看指定类别的帖子。在名为“category”的django视图中,我们只需要选择链接到“sci-fi”类别的帖子。现在我这样做:
def category(request, path):
# 'path' is 'books/sci-fi'
# detect current category code from url
category_slug = path.split('/')[-1]
# get current category object
category = Categories.objects.get(slug = category_slug)
# get child categories
childs = category.get_descendants();
# make list of id for needed categories
ids = [child.id for child in childs]
# add current category id
ids.append(category.id)
# selecting posts for current and nested categories
posts_list = Post.objects.filter(category__in = ids)
它有效,但内心声音表示此代码中有一些不必要的步骤。如何使这段代码更简单有效,你能建议吗?感谢。
答案 0 :(得分:6)
您可以进行一些优化。
首先,in
过滤器接受对象和ID,因此您可以跳过列表理解:
categories = list(category.get_descendants)
categories.append(category)
Post.objects.filter(category__in=categories)
为了获得更大的改进,您需要弄脏嵌套集的实现。我并不完全熟悉它,但是看看树形文档,它看起来与MPTT类似,我明白这一点。如果是这样,我们可以依赖于我们想要的类别具有lft
属性这一事实,该属性的值位于当前类别的lft
和rgt
之间,以便在一个类别中执行整个操作去:
Post.objects.filter(category__lft__range=(category.lft, category.rgt))