2

I wish to update a Django model field of objects in a queryset. To be specific, I want to add a prefix on one of the fields i.e. if an object has a name like 'Wilson', I want to prefix it with 'OLD', then it will become 'OLDWilson'.

I can think of the following using loops:

my_objs = MyObjects.objects.filter(name='some_name') # This has over 40000 records
for obj in my_objs:
    obj.name = 'OLD{0}'.format(obj.name)
    obj.save()

I was hoping of a more elegant way to take advantage of the UPDATE method as specified here: Django Mass Update

Something like the following:

MyObjects.objects.filter(name='some_name').update(name='OLD+name_here')

Any pointers on how I can achieve this?

Frankline
  • 40,277
  • 8
  • 44
  • 75
  • Generally it is not a good idea to put flags directly into the textual data. You should create a field `old` instead, set it to true if needed and add the `OLD` text in your view / template. In other words: devide model and represetation. – Klaus D. Oct 21 '16 at 05:08
  • @Frankline Tried yet ?? – Prakhar Trivedi Oct 21 '16 at 07:56
  • I didn't test my answer yesterday and yeah 'OLD'+F() returns an error, i think I found a similar question which should do what you need: http://stackoverflow.com/questions/8143362/django-using-an-f-expression-for-a-text-field-in-an-update-call – serg Oct 21 '16 at 18:26

3 Answers3

2

This actually works in the latest version of Django as of May 2022

from django.db.models import Value
from django.db.models.functions import Concat

query = MyObjects.objects.filter(name='some_name')
query.update(name=Concat(Value("OLD"), "name"))
Chrisjan
  • 342
  • 2
  • 10
1

Try something like this :

    from django.db.models import F

    Myobj = MyObjects.objects.filter(name='some_name')
    Myobj.update(name='OLD'+ F('name'))
Prakhar Trivedi
  • 8,218
  • 3
  • 28
  • 35
  • Does `F('name')` return a string? Getting the following: `django.db.utils.ProgrammingError: operator does not exist: unknown + character varying LINE 1: ...document" SET "name" = ('OLD' + "registr...` – Frankline Oct 21 '16 at 09:06
  • @Frankline There must be some error in your interpretation of my code. I gave you a solution based on information provided by you.If you can give detailed information (about your model and view) then only I will be able to help you further. – Prakhar Trivedi Oct 21 '16 at 09:29
  • @Frankline The model you mentioned "MyObjects" does have a field called name.Right?? – Prakhar Trivedi Oct 21 '16 at 09:40
  • F objects doesn't support string concatenation. (https://stackoverflow.com/questions/3300944/can-i-use-django-f-objects-with-string-concatenation) – Vaibhav Gupta Dec 13 '18 at 10:14
0

I know this question is almost 5 years old. But, with hopes that this helps the answer be more visible - here goes.

Use Concat from django.db.models.functions like so:

from django.db.models.functions import Concat
from django.db.models import Value
MyObjects.objects.filter(name='some_name').update(name=Concat(Value'OLD', 'name'))

That last line returns the number of rows affected by the update.