Django中的复杂查询

时间:2009-10-19 14:09:35

标签: django django-models

也许是一个简单的问题,但我刚刚开始使用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)

它有效,但内心声音表示此代码中有一些不必要的步骤。如何使这段代码更简单有效,你能建议吗?感谢。

1 个答案:

答案 0 :(得分:6)

您可以进行一些优化。

首先,in过滤器接受对象和ID,因此您可以跳过列表理解:

categories = list(category.get_descendants)
categories.append(category)
Post.objects.filter(category__in=categories)

为了获得更大的改进,您需要弄脏嵌套集的实现。我并不完全熟悉它,但是看看树形文档,它看起来与MPTT类似,我明白这一点。如果是这样,我们可以依赖于我们想要的类别具有lft属性这一事实,该属性的值位于当前类别的lftrgt之间,以便在一个类别中执行整个操作去:

Post.objects.filter(category__lft__range=(category.lft, category.rgt))