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