Django bulk update with string replace
django, django-orm, python
Solution
Tested with django 1.9
from django.db.models import F, Func, Value
ExampleModel.objects.filter(<condition>).update(
string_field=Func(
F('string_field'),
Value('old text'), Value('new text'),
function='replace',
)
)
UPDATE Django 2.1 https://docs.djangoproject.com/en/2.2/ref/models/database-functions/#replace
from django.db.models import Value
from django.db.models.functions import Replace
ExampleModel.objects.filter(<condition>).update(
string_field=Replace('string_field', Value('old text'), Value('new text'))
)
Problem
I am trying to update and modify a string field Django's ORM. The equivalent SQL to do this is: ``` UPDATE example_table SET string_field = REPLACE(string_field, 'old text', 'new text'); ``` With that query, I expect `old text` and `old text more text` to be replaced with `new text` and `new text more text` respectively, for all the entries in the `string_field` column. Bulk update() seems promising, but doesn't allow me to modify only part of the field, and F() expressions only implement numeric changes, not string replace. I also looked at using raw queries to run the above SQL, but that seems like a sideways hack (especially since F() exists to do the same functionality on numbers), and I couldn't get them to actually execute. I ended up with this, but it seems a shame to execute all the extra queries when I know there's a one line SQL statement to do it. ``` for entry in ExampleModel.objects.all(): entry.string_field = entry.string_field.replace('old text', 'new text', 1) entry.save() ``` Does this feature not exist in Django's ORM for strings yet? Is there something I overlooked in the docs? Related SO questions: - generate update query using django orm - SQL statement to remove part of a string