Django queryset额外查询中的语法错误

0 投票
1 回答
797 浏览
提问于 2025-05-10 15:05

下面的内容有一个语法错误:

date = datetime.now()-timedelta(minutes=30)
articles = Article.objects.filter(published=True).extra(select = {
  "views" : """
  SELECT COUNT(*)
  FROM myapp_readership
    JOIN myapp_article on myapp_readership.which_article_id = myapp_article.id
  WHERE myapp_readership.reader_id = myapp_user.id
  AND myapp_readership.what_time > %s """ % date,
}).order_by("-views")

错误信息是:在“01”附近有语法错误(这里的“01”是extra里面的一个日期时间对象)。这个信息不太好理解。有人能告诉我发生了什么吗?


背景:与上面代码相关的模型是:

class Article(models.Model):
    author = models.ForeignKey(User)
    published = models.BooleanField(default=False)

class Readership(models.Model):
    reader = models.ForeignKey(User)
    which_article = models.ForeignKey(Article)
    what_time = models.DateTimeField(auto_now_add=True)

我写这段代码是因为我想获取所有已发布的文章,并按照每篇文章在过去30分钟内的独特阅读量进行排序。也就是说,我想统计每篇已发布文章在过去半小时内有多少个不同的(独特的)浏览量,然后生成一个按这些独特浏览量排序的文章列表。我的代码缺少处理“独特”这一部分的逻辑——我不知道该怎么做。

相关文章:

  • 暂无相关问题
暂无标签

1 个回答

3

你绝对不应该在SQL查询中使用字符串替换,无论这是否是extra调用的一部分。你已经发现了一个原因——因为值没有正确引用——但更重要的原因是,这样做会让你的代码容易受到SQL注入攻击。

相反,应该使用数据库API提供的功能:在这种情况下,使用select_params

.extra(
  select={
    "views" : """
      SELECT COUNT(*)
      FROM myapp_readership
        JOIN myapp_article on myapp_readership.which_article_id = myapp_article.id
      WHERE myapp_readership.reader_id = myapp_user.id
      AND myapp_readership.what_time > %s """
    },
    select_params=(date,),
)

另外,查看一下文档中的说明extra方法已经不推荐使用,查询可以用其他ORM方法来表达。

撰写回答