Django:有没有办法实现“日期范围唯一”?
如果我的物品模型是:
class Item(models.Model):
name = models.CharField(max_length=500)
startDate = models.DateField("Start Date", unique="true")
endDate = models.DateField("End Date")
每个物品都需要有一个独特的日期范围。比如说,如果我创建了一个日期范围是从6月1日到6月8日的物品,那么我该如何防止创建一个日期范围是从6月3日到6月5日的物品(或者用模板逻辑显示一个错误)呢?
请告诉我,如果我可以更清楚地解释这个问题!
2 个回答
7
如果你使用postgresql作为数据库,并且使用的django版本是3.0或更高,那么你可能想要在数据库层面上强制执行一些逻辑(这个方法在之前的答案给出时是不可用的)。
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),
],
)
来源: https://docs.djangoproject.com/en/3.2/ref/contrib/postgres/constraints/
9
你不能在模型层面强制执行这个规则,不过你可以重写保存方法,像这样:
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)
补充一下:也许日期范围的检查可以简单一点,距离我上次做这个已经很久了,但这个例子展示了大致的概念 :).