Assume the following models for this question:

class Jurisdiction(models.Model):
    name = models.CharField(max_length = 100)

class Account(models.Model):
    account_number = models.PositiveIntegerField(blank = True)
    jurisdiction = models.ForeignKey("Jurisdiction", on_delete = models.
CASCADE)

    class Meta:
        """Meta model to define unique_together constraints."""
        #make the account_number unique for a jurisdiction
        unique_together = ("account_number", "jurisdiction")

    def create_account_number(self):
        """Create the account number for this account."""
        # If the account number is already set, do nothing.
        if self.account_number is not None:
            return

        # Get the last account created for the jurisdiction, based on 
having the largest account number.
        last_account_for_jurisdiction = Account.objects.filter(jurisdiction 
= self.jurisdiction).order_by("-account_number").first()
        # If the account exists set the account number.
        if last_account_for_jurisdiction is not None:
            self.account_number = last_account_for_jurisdiction.account_number 
+ 1
        # Else there are no other accounts for this jurisdiction, set the 
first account number.
        else:
            self.account_number = 1

    def save(self, *args, **kwargs):
        # create the account number
        self.create_account_number()
        # call the superclass save to write the account to the database.
        super().save(*args, **kwargs)

Is there a way in Django to be able to atomically set account_number on 
save based on the largest account number for a given jurisdiction? I was 
hoping some combination of F expressions 
<https://docs.djangoproject.com/en/2.2/ref/models/expressions/#f-expressions>, 
conditional expressions 
<https://docs.djangoproject.com/en/2.2/ref/models/conditional-expressions/>, 
and subquery expressions 
<https://docs.djangoproject.com/en/2.2/ref/models/expressions/> would allow 
me to do this, but they don't appear to allow referencing a different 
model's fields.

The unique_together will properly prevent duplicate Jurisdiction + 
account_number pairs from being entered into the DB, but I was hoping there 
was a way to perform the setting of account_number in an atomic way so I 
wouldn't have to handle an IntegrityError and try again. I get the feeling 
what I'm asking for isn't possible, or there's a completely different way I 
should be going about this. I haven't used AutoField as I need a sequental 
series of numbers within each Jurisdiction.

Thanks in advance for the help.

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-users+unsubscr...@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-users/fc7a0001-a576-46e5-b0a1-aeec500ad77c%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to