这些文档展示了一种接受 PostgreSQL 提供的数据完整性约束的方法,例如这ExclusionConstraint
for 重叠范围。
您可以从文档中阅读建议的解决方案here https://docs.djangoproject.com/en/3.1/ref/contrib/postgres/constraints/。
我想要一个预订系统,确保一个“东西”(这里是培训师/老师)不能在重叠的时间段内被预订两次。我将使用文档中的第二个示例,其中重叠标准源自现有字段:
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”。
遗憾的是我在文档中或其他地方都找不到任何关于此的内容,所以any感谢提示并提前致谢。