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
- [Django]-Can't import: 'unable to import rest_framework' when importing serializer? (windows)
- [Django]-Get meta description from external website
- [Django]-Django template includes
- [Django]-Django URL Mapping: How to remove app name from URL paths?
- [Django]-Retrieve HTTP Header in Django RestFrameWork
-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 requireAnother 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.