Django:有没有办法让"日期范围独一无二"?

tom*_*ber 4 python django django-templates django-models

如果我的物品模型是:

class Item(models.Model):
    name = models.CharField(max_length=500)
    startDate = models.DateField("Start Date", unique="true")
    endDate = models.DateField("End Date")      
Run Code Online (Sandbox Code Playgroud)

每个项目都需要具有唯一的日期范围.例如,如果我创建一个项目有6月1日至6月8日的日期范围,我怎能和项目与正在创建6月3日的日期范围,以6月5日(或渲染模板逻辑错误)?

如果我能更好地澄清这个问题,告诉我!

Kil*_*nDS 7

您无法在模型级别强制执行此操作,但您可以将save方法覆盖为以下内容:

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)
Run Code Online (Sandbox Code Playgroud)

编辑:也许日期范围检查可以更容易,我做了很长时间,但它显示了一般概念:).


小智 7

如果您使用 postgresql 作为数据库后端并使用 django >=3 的版本,您可能希望在数据库级别强制执行此逻辑(当给出接受的答案时,此方法不可用)。

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),
                ],
            )
Run Code Online (Sandbox Code Playgroud)

来源: https ://docs.djangoproject.com/en/3.2/ref/contrib/postgres/constraints/