将文字百分号传递给 QuerySet.extra()

Posted

技术标签:

【中文标题】将文字百分号传递给 QuerySet.extra()【英文标题】:Passing literal percent sign to QuerySet.extra() 【发布时间】:2015-02-20 08:26:37 【问题描述】:

我想执行以下代码:

 Booking.objects.filter(start_ts__isnull = False, end_ts__isnull = False).extra(select = 'amount': "strftime('%s', end_ts) - strftime('%s', start_ts)")

但是,在 shell 中,我收到以下错误:

Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/home/polesz/Projects/duckbook/venv/lib/python3.4/site-packages/django/db/models/query.py", line 835, in extra
    clone.query.add_extra(select, select_params, where, params, tables, order_by)
  File "/home/polesz/Projects/duckbook/venv/lib/python3.4/site-packages/django/db/models/sql/query.py", line 1744, in add_extra
    entry_params.append(next(param_iter))
StopIteration

我尝试将百分号加倍 (%%s) 并用反斜杠 (\%s) 转义它们,但都没有帮助。我还查看了this answer,但该解决方案不适用于QuerySet.extra()(或者我只是错过了重点)。

解决这个问题的正确方法是什么?

编辑:我也尝试像这样使用select_params

Booking.objects.filter(start_ts__isnull = False, end_ts__isnull = False).extra(select = 'amount': "strftime('%s', end_ts) - strftime(%s, start_ts)", select_params = ['%s', '%s'])

但不管使用引号,结果查询都有\'%s\',这当然会给出一个SQL错误。

【问题讨论】:

你知道这个问题的答案了吗?如果是,请发布此问题的正确答案。 还没有,但我仍然感兴趣(尽管该项目现在已经转移到 PostgreSQL)。 【参考方案1】:

我遇到了完全相同的问题,想在这里跟进。

我通过使用带有双百分号的 .format 方法解决了这个问题。例如,如果您有一个带有date_fieldFoo 模型,并且想要执行一个SQL 方法date_format(date_field, '%Y-%m'),您可以在Django 1.7 ORM 中这样做:

Foo.objects.extra(
    select='formatted_date': 
        "date_format(date_field, 'param')".format(param='%%Y-%%m')
)

供您参考,在 Django 1.7 中有一个错误,不允许将文字 %s 直接传递给额外的选择。此问题已得到修复,链接如下:https://code.djangoproject.com/ticket/23460

【讨论】:

以上是关于将文字百分号传递给 QuerySet.extra()的主要内容,如果未能解决你的问题,请参考以下文章

Django extra + where:如何转义标识符

将数组文字传递给 PostgreSQL 函数

为啥 PHP 在一种情况下允许将文字传递给按引用传递的参数,而在其他情况下不允许?

Echats给柱状图及提示文字添加百分号(%)的解决办法

Echats给柱状图及提示文字添加百分号(%)的解决办法

为啥将字符串文字传递给 char* 参数有时只是编译器错误?