首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >清洁期望的ExclusionConstraint IntegrityError在Django的管理或形式

清洁期望的ExclusionConstraint IntegrityError在Django的管理或形式
EN

Stack Overflow用户
提问于 2020-12-21 09:45:28
回答 1查看 207关注 0票数 1

文档展示了一种包含PostgreSQL提供的数据完整性约束的方法,f.e。重叠区域的ExclusionConstraint。您可以从docs 这里中读取建议的解决方案。我想有一个预订系统,以确保一个“东西”(这里是一个教练/教师)不能在重叠的时间内两次预订。下面是文档中的第二个例子,其中的重叠标准是从现有字段派生的:

代码语言:javascript
复制
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:

代码语言:javascript
复制
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”。

遗憾的是,我在文档中找不到任何关于这件事的东西,也找不到其他任何地方,所以任何提示都会提前得到赏识。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-12-22 11:02:44

因此,我想不可能重用约束来查询重叠事件,因为Django试图将一个对象保存到数据库中,至少从我可以找到的内容来看,它已经被清除了。无论如何,我当然会保留约束,因为这是对数据完整性的有力保证,但是为了获得我想要的功能,我在模型中添加了一个自定义管理器。

如下所示,它适合于“带预订的房间”模式(只需将培训师替换为Room),但是您需要根据需要修改它。

代码语言:javascript
复制
from django.db import models


class TrainingEventManager(models.Manager):
    def check_availability(self, trainer, start, end):
        return not (
            super()
            .get_queryset()
            .filter(trainer=trainer)
            .filter(start__gte=start)
            .filter(end__lte=end)
            .exists()
        )

它查询给定的日期时间范围(start__gteend__lte),检查它是否有条目(exists()),并返回与之相反的布尔值,因为我想知道可用性,而不是"is_reserved“答案。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65390532

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档