Django:在更新调用中为文本字段使用F表达式 [英] Django: Using an F expression for a text field in an update call

查看:403
本文介绍了Django:在更新调用中为文本字段使用F表达式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在django视图中,我需要将字符串数据附加到数据库中现有文本列的末尾。所以,例如说我有一个名为ATable的表,它有一个名为aField的字段。我希望能够以无条件的方式将字符串附加到aField的末尾。最初,我有这样的:

In a django view, I need to append string data to the end of an existing text column in my database. So, for example, say I have a table named "ATable", and it has a field named "aField". I'd like to be able to append a string to the end of "aField" in a race-condition-free way. Initially, I had this:

tableEntry = ATable.objects.get(id=100)
tableEntry.aField += aStringVar
tableEntry.save()

问题是如果同时执行,都可以得到相同的tableEntry,然后它们各自独立更新,最后一个保存获胜,丢失另一个附加的数据。

The problem is that if this is being executed concurrently, both can get the same "tableEntry", then they each independently update, and the last one to "save" wins, losing the data appended by the other.

I看到这一点,发现这个,我希望工作,使用F表达式:

I looked into this a bit and found this, which I hoped would work, using an F expression:

ATable.objects.filter(id=100).update(aField=F('aField') + aStringVar)

,我收到一个SQL错误,说:

The problem here, is I get an SQL error, saying:

operator does not exist: text + unknown
HINT:  No operator matches the given name and argument type(s). You might need to add explicit type casts.

尝试改为str(aStringVar)即使它已经是一个字符串 - 没有运气..我发现几个django错误报告抱怨类似的问题,但我没有看到修复或解决方法。有没有一些方法可以使用AStringVar来将它附加到F表达式的文本? BTW - 也尝试过str(F('aField'))+ aStringVar,但将F表达式的结果转换为字符串(DEFAULT:)。<​​/ p>

Tried changing to "str(aStringVar)" even though its already a string - no luck.. I found a couple django bug reports complaining about similar issues, but I didn't see a fix or a workaround. Is there some way I can cast aStringVar such that it can be appended to the text of the F expression? BTW - also tried "str(F('aField')) + aStringVar" but that converted the result of the F expression to the string "(DEFAULT: )".

推荐答案

您可以通过一个简单的更改覆盖Django中的 F 对象:

You can override F object in Django with one simple change:

class CF(F):
    ADD = '||'

然后只需使用 CF 代替 F 。它将放置||而不是在生成SQL时使用+。例如,查询:

Then just use CF in place of F. It will place "||" instead of "+" when generating SQL. For example, the query:

User.objects.filter(pk=100).update(email=CF('username') + '@gmail.com')

将生成SQL:

UPDATE "auth_user" SET "email" = "auth_user"."username" || '@gmail.com'
WHERE "auth_user"."id" = 100 

这篇关于Django:在更新调用中为文本字段使用F表达式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆