I have a model with a unique integer that needs to increment with regards to a foreign key, and the following code is how I currently handle it:
class MyModel(models.Model):
business = models.ForeignKey(Business)
number = models.PositiveIntegerField()
spam = models.CharField(max_length=255)
class Meta:
unique_together = (('number', 'business'),)
def save(self, *args, **kwargs):
if self.pk is None: # New instance's only
try:
highest_number = MyModel.objects.filter(business=self.business).order_by('-number').all()[0].number
self.number = highest_number + 1
except ObjectDoesNotExist: # First MyModel instance
self.number = 1
super(MyModel, self).save(*args, **kwargs)
I have the following questions regarding this:
- Multiple people can create
MyModel
instances for the samebusiness
, all over the internet. Is it possible for 2 people creatingMyModel
instances at the same time, and.count()
returns 500 at the same time for both, and then both try to essentially setself.number = 501
at the same time (raising an IntegrityError)? The answer seems like an obvious "yes, it could happen", but I had to ask. - Is there a shortcut, or "Best way" to do this, which I can use (or perhaps a
SuperAutoField
that handles this)?
I can't just slap a while model_not_saved:
try:
, except IntegrityError:
in, because other restraints in the model could lead to an endless loop, and a disaster worse than Chernobyl (maybe not quite that bad).