这些文档展示了一种接受PostgreSQL提供的数据完整性约束的方法,例如重叠范围的ExclusionConstraint
。
您可以从文档here中阅读建议的解决方案。
我想有一个预约系统,确保一个“东西”(这里是一个培训师/老师)在一段重叠的时间内不会被预订两次。我将使用文档中的第二个示例,其中重叠标准来自现有字段:
from django.contrib.postgres.constraints import ExclusionConstraint
from django.contrib.postgres.fields import (
DateTimeRangeField,
RangeBoundary,
RangeOperators,
)
from django.db import models
from django.db.models import Func, Q
class TsTzRange(Func):
function = 'TSTZRANGE'
output_field = DateTimeRangeField()
class Reservation(models.Model):
trainer = models.ForeignKey('Trainer', on_delete=models.CASCADE)
start = models.DateTimeField()
end = models.DateTimeField()
cancelled = models.BooleanField(default=False)
class Meta:
constraints = [
ExclusionConstraint(
name='exclude_overlapping_reservations',
expressions=(
(TsTzRange('start', 'end', RangeBoundary()), RangeOperators.OVERLAPS),
('trainer', RangeOperators.EQUAL),
),
condition=Q(cancelled=False),
),
]
因此,这对我来说很好,当试图保存无效范围时,我将得到预期的IntegrityError:
IntegrityError at /admin/trainer/trainingevent/add/
conflicting key value violates exclusion constraint "exclude_overlapping_reservations"
DETAIL: Key (tstzrange(start, "end", '[)'::text), trainer_id)=(["2020-12-19 16:20:00+00","2020-12-19 16:55:00+00"), 1) conflicts with existing key (tstzrange(start, "end", '[)'::text), trainer_id)=(["2020-12-19 16:15:00+00","2020-12-19 16:45:00+00"), 1).
这就引出了我的问题:
如何验证字段,或者更确切地说,如何创建一个适当的clean()
方法来验证输入,而不复制功能?
从我目前的角度来看,最好是要求PostgreSQL以某种方式进行检查,或者以某种方式将模型保存在try-catch块中
因此,在更一般的情况下,这个问题应该等同于“如何清理Django中的IntegrityError”
遗憾的是,我在文档中或其他任何地方都找不到与此相关的任何信息,因此,请提前向我提供任何提示和thx
因此,我想不可能重复使用约束来查询重叠事件,因为在Django试图将对象保存到数据库时,它已经被清理了,至少从我能找到的情况来看是这样的。 无论如何,我当然会让约束保持活动状态,因为这是对我的数据完整性的有力保证,但是为了获得我想要的功能,我已经在模型中添加了一个自定义管理器
如下所示,它符合“带预订的房间”模式(只需将培训师替换为房间),但您需要根据自己的需要对其进行修改
它查询给定的日期时间范围(
start__gte
和end__lte
),检查它是否有条目(exists()
),并返回布尔值,因为我想知道可用性而不是“保留”答案相关问题 更多 >
编程相关推荐