【发布时间】:2018-03-12 18:57:55
【问题描述】:
[在完成 Django 官方教程和 Django Girls 教程之后],我开始了我的第一个 Django 博客应用程序。我在理解 Django ORM 时遇到了一些麻烦。我有这个有效的 SQL 查询,但我觉得它效率很低,我宁愿在继续之前学习正确的方法。
Post.objects.raw(('SELECT * FROM (SELECT id, category, body, slug, author, title,
published, row_number() OVER (PARTITION BY category) as rownum FROM post) tmp
WHERE rownum < 5'))
基本上我想为每个帖子类别显示最后 5 行。上面的代码已经可以工作了,问题是当我循环遍历模板中的每个帖子时,它会在调用 Post 的 get_absolute_url 方法时为每个帖子运行额外的查询。我使用 Django 的 {% url %} 标记修复了这个问题,但仍然运行了 7 个额外的查询,我想将其限制为最多 2-3 个。
我有一个这样的模型:
class Post(models.Model):
title = models.CharField(max_length=250)
category = models.CharField(max_length=30, choices=CATEGORY_CHOICES)
tags = TaggableManager()
slug = models.SlugField(max_length=250, unique_for_date='published')
author = models.CharField(max_length=50)
body = HTMLField('body')
published = models.DateTimeField(default=timezone.now)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
status = models.CharField(max_length=10, choices=STATUS_CHOICES,
default='draft')
class Meta:
ordering = ('-published',)
db_table = 'post'
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('post_detail', args=[self.category, self.slug])
我尝试了几个小时通过 ORM 让它工作,但无法让它工作。我最终在原始 SQL 中执行此操作,但我不知道会运行 20 多个附加查询。主要目标是显示按发布日期排序的每个类别的最后 5 个帖子。我正在使用 PostgreSQL。
【问题讨论】:
-
+1。您的解决方案几乎完成了。需要一个小修复来获得正常的对象,实际上最后 5 个帖子不是随机的 5 个帖子。
标签: sql django django-models django-queryset django-orm