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

时间:2014-12-22 08:48:03

标签: python django sqlite python-3.x django-1.7

我想执行以下代码:

 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错误。

1 个答案:

答案 0 :(得分:1)

我有完全相同的问题,并想在此处跟进。

我通过使用带有双百分号的.format方法解决了这个问题。例如,如果您的Foo模型带有date_field且想要执行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