I'm trying to create MyModel
object but I want to set bar
field to incremented value of already existed largest bar
value in db for specified foo
. The problem here are race conditions. I wanted to perform all logic on db side in one step without sucess. I have found solution but it's not the most elegant way. Infinite loops are always bad idea.
from django.db import models, IntegrityError
from django.db.models import Max
class MyModel(models.Model):
foo = models.UUIDField(default=uuid4)
bar = models.PositiveIntegerField()
class Meta:
constraints = [
models.UniqueConstraint(
fields=['id', 'other_id'],
name='unique_id_other_id'
)
]
@classmethod
def create_my_model(cls, data):
while True:
bar = (cls.objects.filter(foo=data['foo']).aggregate(Max('bar')).get('bar_max')
or 0) + 1
try:
cls.objects.create(bar=bar, **data)
except IntegrityError:
continue
I will be glad if anyone can point me any direction how to handle this. BR
Use django.db.models.AutoField
class MyModel(models.Model):
foo = models.UUIDField(primary_key=True, default=uuid4)
bar = models.AutoField()
An IntegerField that automatically increments according to available IDs. You usually won't need to use this directly; a primary key field will automatically be added to your model if you don't specify otherwise. See Automatic primary key fields.
https://docs.djangoproject.com/en/3.0/ref/models/fields/#autofield
Though personally I'll just do the following and leave the primary key alone (which is the de facto way of doing things in Django)
class MyModel(models.Model):
foo = models.UUIDField(unique=True, default=uuid4)
which will give MyModel
an automatic primary key field
id = models.AutoField(primary_key=True)
https://docs.djangoproject.com/en/3.0/topics/db/models/#automatic-primary-key-fields
or if you want to rename the automatic primary key field:
class MyModel(models.Model):
bar = models.AutoField(primary_key=True)
foo = models.UUIDField(unique=True, default=uuid4)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.