user2950593
user2950593

Reputation: 9647

change model property by another property django

I have model Word

class Word(models.Model): 
   group_id = models.IntegerField()
   old_group_id = models.IntegerField(default=0)

I have some word query:

words = Word.objects.filter(...)

Right now I want every word to set old_group_id to group_id something like words.update(old_group_id=group_id) So far I am doing it by iterating through every word, but this doesn't feel very effective:

for word in words:
  word.old_group_id = word.group_id
  word.save()

Upvotes: 1

Views: 136

Answers (2)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 477824

You can do this by using an F(..) expression:

from django.db.models import F

Word.objects.filter(...).update(old_group_id=F('group_id'))

An F-expression [Django-doc] is a way to refer to a model field, instead of using a value (you can also use double underscores to look "through" relations).

The above will thus result in a query like:

UPDATE word
SET old_group_id = group_id
WHERE ...

The update is thus done at the database level. So there is no iteration involved at the Django/Python side. This will thus (nearly) always outperform changing the model object at the Django/Python layer: it reduces the amount of queries from O(n) to O(1), and furthermore databases are usually optimized to do updates "in bulk".

Upvotes: 1

Daniel Roseman
Daniel Roseman

Reputation: 600059

You can use F objects.

words.update(old_group_id=F('group_id'))

Upvotes: 1

Related Questions