【问题标题】:Django custom validation before the data is saved (Enforce at the database level)保存数据前的 Django 自定义验证(在数据库级别强制执行)
【发布时间】:2020-06-30 08:03:35
【问题描述】:

这是我的帖子preventing crud operations on django model的扩展

问题的简述,我目前使用一个名为django-river 的包在我的应用程序中实现工作流系统。问题是它们没有预定义的 'start' 、 'dropped' 、 'completed' 状态。它们的状态存储为 django 模型实例。这意味着我的应用程序无法以编程方式区分状态。因此,这些状态的标签必须硬编码到我的程序中(或者是吗?也许有人对此有解决方案?)

假设除了将状态硬编码到我的应用程序中之外没有其他解决方案,这意味着我将不得不阻止用户更新或删除我最初预先创建的这些状态。

我的想法是在 django 模型的 save 方法中进行验证检查。此检查将检查 State 模型的前 3 个实例是否始终为 startdeactivatedcompleted 并且顺序相同。这将阻止每当用户尝试在 ORM 级别更改项目时检查通过。

但是,这似乎有两个问题:

  1. 我相信 django admin 没有运行模型类 save 方法

  2. 只要他们改变状态的方式不通过save() 方法,人们仍然可以改变状态。来自 DB SQL 命令的 AKA

虽然不太可能发生,但更改名称会“破坏”我的应用程序,因此我希望非常确定没有人可以编辑和更改这 3 个预定义状态。

有没有万无一失的方法来做到这一点?

【问题讨论】:

    标签: django


    【解决方案1】:

    我的想法是在 django 模型的保存方法中进行验证检查。

    如果我理解您的描述,也许您可​​以像这样覆盖模型的 save() 函数:

    class MyModel(models.Model):
    
    [..]
    
        def save(self, *args, **kwargs):
    
            # Put your logic here ..
    
            super(MyModel, self).save(*args, **kwargs)
    

    【讨论】:

    • 我担心的是某些创建模型实例的方法没有通过save方法。假设它是由 django 管理员或 sql 命令创建的
    【解决方案2】:

    我从 django documentation得到了答案

    from django.core.exceptions import ValidationError
    from django.utils.translation import gettext_lazy as _
    
    def validate_even(value):
        if value % 2 != 0:
            raise ValidationError(
                _('%(value)s is not an even number'),
                params={'value': value},
            )
    

    您可以通过字段的验证器参数将其添加到模型字段:

    from django.db import models
    
    class MyModel(models.Model):
        even_field = models.IntegerField(validators=[validate_even])
    

    仅供参考:使用 gettext_lazy 并不是必须的,您可以只使用如下消息

    from django.core.exceptions import ValidationError
    
    def validate_even(value):
        if value % 2 != 0:
            raise ValidationError(
                ('%(value)s is not an even number'),
                params={'value': value},
            )
    

    【讨论】:

    • 由于我要编辑的模型来自第三方包,我想检查一下这个方法是否适用于'代理模型'
    猜你喜欢
    • 1970-01-01
    • 2012-02-23
    • 2012-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-20
    • 1970-01-01
    • 2010-10-02
    相关资源
    最近更新 更多