Django: Is there any way to have "unique for date range"?
If my model for Items is:
class Item(models.Model):
name = models.CharField(max_length=500)
startDate = models.DateField("Start Date", unique="true")
endDate = models.DateField("End Date")
开发者_如何学运维
Each Item needs to have a unique date range. for example, if i create an Item that has a date range of June 1st to June 8th, how can I keep and Item with a date range of June 3rd to June 5th from being created (or render an error with template logic)?
PLEASE let me know if I can clarify this question better!
You can not enforce this on the model level, you can however override the save method to something like this:
class Item(models.Model):
name = models.CharField(max_length=500)
startDate = models.DateField("Start Date", unique="true")
endDate = models.DateField("End Date")
def save(self, *args, **kwargs):
try:
Item.objects.get(Q(startDate__range=(self.startDate,self.endDate))|Q(endDate__range=(self.sartDate,self.endDate))|Q(startDate__lt=self.startDate,endDate__gt=self.endDate))
#raise some save error
except Item.DoesNotExist:
super(Item,self).save(*args,**kwargs)
edit: maybe the date range check can go easier, long time since I did it, but it shows the general concept :).
If you use postgresql as a database backend and use a version of django >=3, you'll probably want to enforce this logic at the database level (this approach wasn't available when the accepted answer was given).
from django.contrib.postgres.constraints import ExclusionConstraint
from django.contrib.postgres.fields import DateRangeField, RangeOperators
from django.db import models
class Item(models.Model):
name = models.CharField(max_length=500)
date_range = DateRangeField()
class Meta:
constraints = [
ExclusionConstraint(
name='exclude_overlap',
expressions=[
('date_range', RangeOperators.OVERLAPS),
],
)
Source: https://docs.djangoproject.com/en/3.2/ref/contrib/postgres/constraints/
精彩评论