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

Python Django queryset额外查询中的语法错误,python,sql,django,django-queryset,Python,Sql,Django,Django Queryset,以下内容包含语法错误: 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_a

以下内容包含语法错误:

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中的datetime对象)。没什么可谈的。有人能指出发生了什么事吗


背景:与上述代码相关的型号为:

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分钟内每篇文章所经历的独特读者群进行排序。也就是说,计算在过去的半小时内,每篇发表的文章获得了多少不同(独特)的视图,然后生成一个按这些不同视图排序的文章列表。我的代码缺少处理需求的“独特”部分——我不知道如何在这里实现这一点

您永远不应该在SQL查询中使用字符串替换,无论这是否是额外调用的一部分。您已经发现了一个原因——因为没有正确引用值——但更重要的原因是它让您可以接受SQL注入

相反,使用db 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方法表示。

在SQL查询中永远不应该使用字符串替换,无论它是否是
extra
调用的一部分。您已经发现了一个原因——因为没有正确引用值——但更重要的原因是它让您可以接受SQL注入

相反,使用db 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方法表示。

尝试将
%s
括在引号中(即
myapp\u readership.what\u time>'%s'
)。如果有帮助的话,考虑一下其他一些构建查询的方式——字符串格式是最坏的(实用的)OnDetring包装>代码> %S/<代码>引用(因此是<代码> MyAppRead Errest.WoTyTime> '%s' )。如果这有帮助的话,请考虑其他一些构建查询的方式——字符串格式是最坏的(实用的)。