Python 如何避免Django模型中的日期重叠?

Python 如何避免Django模型中的日期重叠?,python,django,datetime,django-models,Python,Django,Datetime,Django Models,我有一个模型: class Dimension_Item(models.Model): uq_dimension_item_id = MyCharField(max_length=1024, primary_key=True) dimension_id = MyCharField(max_length=1024) dimension_item_id = MyCharField(max_length=100) name = MyCharField(max_lengt

我有一个模型:

class Dimension_Item(models.Model):
    uq_dimension_item_id = MyCharField(max_length=1024, primary_key=True)
    dimension_id = MyCharField(max_length=1024)
    dimension_item_id = MyCharField(max_length=100)
    name = MyCharField(max_length=255)
    description = MyCharField(max_length=512, null = True)
    start_date = models.DateField(default=date(1,1,1))
    end_date = models.DateField(default=date(9999,12,31))
用于向模型添加信息的函数:

def addRows(in_args):
    rq = in_args[0]
    pk_l=[]
    rows = rq['rows']
    if type(rows).__name__ == 'dict':
        dim = Dimension_Item(
                        name=rows['name'],
                        start_date=rows['start_date'],
                        end_date=rows['end_date']
        )
        dim.save()
        pk_l.append(dim.dimension_id)
    elif type(rows).__name__ == 'list':
        for i in rows:
            dim = Dimension_Item(
                        name=rows['name'],
                        start_date=rows['start_date'],
                        end_date=rows['end_date']
            )
            dim.save()
            pk_l.append(dim.dimension_id)
    else:
        pass
    return getRows(in_args, pk_l)
    # return "success add row"
clauses.addMethod(addRows)
和用于修改模型项的功能:

def modifyRows(in_args):
    pk_l=[]
    rq = in_args[0]
    rows = rq['rows']
    if type(rows).__name__ == 'dict':
        dim = Dimension_Item.objects.get(pk=rows['pk'])
        for attr in rows:
            if attr!='pk':
                try:
                    setattr(dim, attr, rows[attr])
                except KeyError:
                    pass
        dim.save()
        pk_l.append(dim.dimension_id)
    elif type(rows).__name__ == 'list':
        for i in rows:
            dim = Dimension_Item.objects.get(pk=i['pk'])
            for attr in i:
                if i!='pk':
                    try:
                        setattr(dim, attr, i[attr])
                    except KeyError:
                        pass
            dim.save()
            pk_l.append(dim.dimension_id)
    else:
        pass
    return getRows(in_args, pk_l)
    # return "success modify"
clauses.addMethod(modifyRows)
我应该检查“开始日期”和“结束日期”字段是否与数据库中的其他记录重叠

例如,我输入:2.02.1988-3.07.1989。如果我已经有1989年7月2日-1990年8月3日的记录,我必须抛出一个关于日期重叠的例外


我能做得更好吗?

我会覆盖
Dimension\u项
模型的
save()
方法

在自定义save()方法中,可以实现对重叠日期的检查。如果一切正常,请创建对象。如果不是,只返回nothing(或raise和error)

Django文档很好地解释了这一点:

以下是一些(未经测试的)代码,让您开始:

class Dimension_Item(models.Model):
    start_date = models.DateField(default=date(1,1,1))
    end_date = models.DateField(default=date(9999,12,31))

    def save(self, *args, **kwargs):
        # get number of items that have an overlapping start date
        dimension_items_overlapping_start = Dimension_Item.objects.filter(start_date__gte=self.start_date, start_date__lte=self.end_date).count()

        # get number of items that have an overlapping end date
        dimension_items_overlapping_end = Dimension_Item.objects.filter(end_date__gte=self.start_date, end_date__lte=self.end_date).count()

        overlapping_dimension_items_present = dimension_items_overlapping_start > 0 or dimension_items_overlapping_end > 0

        if overlapping_dimension_items_present:
            return 
        else:
            super(Dimension_Item, self).save(*args, **kwargs) # Call the "real" save() method.

谢谢,但我对搜索日期集更感兴趣。您建议如何在Django中实现它?我添加了一些应该可以工作的示例代码。(尽管我没有测试它)这不适用于
self
的范围可以适应另一个现有对象的情况。
class Dimension_Item(models.Model):
    start_date = models.DateField(default=date(1,1,1))
    end_date = models.DateField(default=date(9999,12,31))

    def save(self, *args, **kwargs):
        # check for items that have an overlapping start date
        dimension_items_overlapping_start = Dimension_Item.objects.filter(start_date__gte=self.start_date, start_date__lte=self.end_date).exists()

        # check for items that have an overlapping end date
        dimension_items_overlapping_end = Dimension_Item.objects.filter(end_date__gte=self.start_date, end_date__lte=self.end_date).exists()

        # check for items that envelope this item
        dimension_items_enveloping = Dimension_Item.objects.filter(start_date__lte=self.start_date, end_date__gte=self.end_date).exists()

        overlapping_dimension_items_present = dimension_items_overlapping_start or dimension_items_overlapping_end or dimenstion_items_enveloping

        if overlapping_dimension_items_present:
            return 
        else:
            super(Dimension_Item, self).save(*args, **kwargs) # Call the "real" save() method.