Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using existing field values in django update query

I want to update a bunch of rows in a table to set the id = self.id. How would I do the below?

from metadataorder.tasks.models import Task
tasks = Task.objects.filter(task_definition__cascades=False)
        .update(shared_task_id=self.id)

The equivalent SQL would be:

update tasks_task t join tasks_taskdefinition d
    on t.task_definition_id = d.id
set t.shared_task_id = t.id
    where d.cascades = 0
like image 279
David542 Avatar asked Dec 02 '13 20:12

David542


People also ask

How do I update a specific field in Django?

Use update_fields in save() If you would like to explicitly mention only those columns that you want to be updated, you can do so using the update_fields parameter while calling the save() method. You can also choose to update multiple columns by passing more field names in the update_fields list.

How Django knows to update VS insert?

The doc says: If the object's primary key attribute is set to a value that evaluates to True (i.e. a value other than None or the empty string), Django executes an UPDATE. If the object's primary key attribute is not set or if the UPDATE didn't update anything, Django executes an INSERT link.

How do I add a field to an existing model in Django?

To answer your question, with the new migration introduced in Django 1.7, in order to add a new field to a model you can simply add that field to your model and initialize migrations with ./manage.py makemigrations and then run ./manage.py migrate and the new field will be added to your DB. Save this answer.


2 Answers

You can do this using an F expression:

from django.db.models import F
tasks = Task.objects.filter(task_definition__cascades=False)
    .update(shared_task_id=F('id'))

There are some restrictions on what you can do with F objects in an update call, but it'll work fine for this case:

Calls to update can also use F expressions to update one field based on the value of another field in the model.

However, unlike F() objects in filter and exclude clauses, you can’t introduce joins when you use F() objects in an update – you can only reference fields local to the model being updated. If you attempt to introduce a join with an F() object, a FieldError will be raised[.]

https://docs.djangoproject.com/en/dev/topics/db/queries/#updating-multiple-objects-at-once

like image 159
Peter DeGlopper Avatar answered Oct 07 '22 16:10

Peter DeGlopper


I stumbled upon this topic and noticed Django's limitation of updates with foreign keys, so I now use raw SQL in Django:

from django.db import connection
with connection.cursor() as cursor:
    cursor.execute("UPDATE a JOIN b ON a.b_id = b.id SET a.myField = b.myField")
like image 23
Peter Avatar answered Oct 07 '22 17:10

Peter