Home > Blockchain >  Django models normalization
Django models normalization

Time:07-10

having a simple ordinary model like this

class Order(models.Model):
    open = models.DecimalField(max_digits=10, decimal_places=8)
    high = models.DecimalField(max_digits=10, decimal_places=8)
    low = models.DecimalField(max_digits=10, decimal_places=8)
    close = models.DecimalField(max_digits=10, decimal_places=8)
    time = models.DateTimeField()
    active = models.BooleanField(default=False)
    complete = models.BooleanField(default=False)

works for my case but as there's only up to 1 active order at the same time, keeping it consistent is a challenge. don't wanna use transaction so the idea of separating active attribute would be a solution. I wondered if there's any better idea? for example, adding active as a database related attribute or something like a hook (believe me when I say I don't know if that's an option)

CodePudding user response:

You can use a UniqueConstraint [Django-doc] to enforce that at most one Order has active=True:

from django.db.models import Q

class Order(models.Model):
    # …
    active = models.BooleanField(default=False)

    class Meta:
        constraints = [
            models.UniqueConstraint(
                fields=('active',),
                condition=Q(active=True),
                name='at_most_one_active'
            )
        ]

CodePudding user response:

what about checking this before save


class Order(models.Model):
  ...
  

  def save(self,*args,**kwargs):
    if self.active: # then will check in the DB 
       objs = self.__class__.objects.filter(...).values_list(flat=True) # put your filters 
    if any(objs): # check if there is any True Value 
       raise MultiActiveOrdersError("Only On Order Can be Active")
    else :
      super().save(*args,*kwargs)

So you can Create the Object but to save it into the DB, it mustn't be any active ones else

  • Related