[Django]-Django – update_or_create

4👍

The problem is that you don’t know the value of total in the event that update_or_create needs to create an object. If you specify a default value like so

class XYZ(models.Model):
    unique_col = models.CharField(max_length=255)
    total = models.IntegerField(default=0)

Then you can run a get_or_create and do the update afterwards.

obj, created = XYZ.objects.get_or_create(unique_col='unique_value')
obj.total += 10
obj.save()

Granted this doesn’t use the update_or_create method if you’d really like to use that, but it at least gets you out of needing the try/except, if that was what you were hoping to avoid

3👍

An updated answer for 2020:
The concept of Robert’s answer is correct but I had to modify it in the following way to work for me:

Set default for total to zero:

class XYZ(models.Model):
    ...
    total = models.IntegerField(default=0)

Set obj, created not just obj

obj, created = XYZ.objects.get_or_create(unique_col='unique_value')
obj.total += 10
obj.save()

See https://docs.djangoproject.com/en/3.0/ref/models/querysets/#get-or-create

-1👍

I think the best way to solve this is by using F expressions when updating the total field:

from django.db.models import F

obj, create = XYZ.objects.get_or_create(unique_col="unique_col")
obj.total = F('total') + 10
obj.save()

Django F expression docs

An F() object represents the value of a model field or annotated
column. It makes it possible to refer to model field values and
perform database operations using them without actually having to pull
them out of the database into Python memory.

When Django encounters an instance of F(), it overrides the standard
Python operators to create an encapsulated SQL expression;

F() can be used on QuerySets of object instances, with update(). This
reduces the two queries we were using before – the get() and the
save() – to just one.

F() therefore can offer performance advantages by:
getting the database, rather than Python, to do work reducing the number of
queries some operations require

Another useful benefit of F() is that having the database – rather
than Python – update a field’s value avoids a race condition.

Django supports the use of addition, subtraction, multiplication,
division, modulo, and power arithmetic with F() objects, both with
constants and with other F() objects. Instead, Django uses the F()
object to generate a SQL expression that describes the required
operation at the database level.

Leave a comment