问题
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
回答1:
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 infilter
andexclude
clauses, you can’t introduce joins when you useF()
objects in anupdate
– you can only reference fields local to the model being updated. If you attempt to introduce a join with anF()
object, aFieldError
will be raised[.]
https://docs.djangoproject.com/en/dev/topics/db/queries/#updating-multiple-objects-at-once
回答2:
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")
来源:https://stackoverflow.com/questions/20337619/using-existing-field-values-in-django-update-query