只要你的Web开发知识不是语文老师教的,那么你应该已经知道一个合格的开发者应该永远抱着怀疑的眼光看用户提交的数据。你不仅需要在前端通过表单或其它方式进行验证,还需要在后台视图拿到用户发送的数据后再对其进行验证一遍。假如有一天你开发一个少儿不宜的网站,你的用户模型里有年龄(age)这个字段而你要求每个注册用户年龄都大于18岁,在Django中你当然可以自定义表单的clean方法, 自定义validators或者重写模型的save方法对年龄字段进行验证。然而你想过没有一件事没有?这能阻止某个员工或用户通过Django的admin后台或数据库可视化工具对数据库进行修改,把用户的年龄修改到18岁以下吗?当然不能。
划重点:前后端的数据验证并不能保证数据库里数据的正确性和有效性,在数据库层面添加一些约束条件是最根本的解决方法。
今天我们就来看下如何在Django项目中给数据库添加约束(Constraints)。
什么是数据库约束(db constraints)基本常识
数据库约束(Contraints)是在数据库层面对表中的数据进行进一步的限制, 保证数据的正确性、有效性和完整性(data integrity)。 约束通常与一个表相关联,并使用CREATE CONSTRAINT或CREATE ASSERTION SQL语句创建。他们定义数据库中的数据必须符合的某些属性。他们可以应用于列,整个表格,多个表格或整个模式。
常见的约束条件有:
在Django中我们可以借助于它的ORM,而不是原始SQL语句创建约束,所以对SQL语句不熟悉的不用担心看不懂本文。not null和primary key这两个约束Django通常在创建数据表时会自动帮你加上,比如primary key永远是唯一的。如果你在定义模型时给某个字段设置了null=True, 那么Django就会取消not null的自动约束。
今天我们着重看下如何添加unique和check这两个常用的数据库约束。
UniqueConstraint (唯一约束)
假如我们有如下一个员工(employee)模型,我们希望让姓名(name)和email这个组合变得唯一,我们可以在Meta选项中定义一个unique_together元组。这样Django会自动为你创建数据库约束。
同样需要unique_together的字段组合还有(room, date)等。当你试图注册相同用户名和用户email时,你会得到如下报错:
由于unique_together这个方法将来会被淘汰,Django 2.2后建议在Meta.constraints选项中定义UniqueConstraints。它有两个属性,一是需要unique的字段或字段组合(fields),二是要给它取个名字(name)。
CheckConstraint(条件约束)
条件约束确保一个模型实例只有满足一定的规则条件后才被创建,不满足条件的数据不会存入到数据库。下例增加了一个对员工年龄的约束,只有大于18岁的才能注册。
无论你使用UniqueConstraint还是CheckConstraint都必须给它取一个独一无二的名字。
前后端数据验证并不能总是保证数据库里数据的有效性和完整性。Django中可以通过Meta.constraints选项轻松定义数据库层面的UniqueConstraint(唯一约束)和CheckConstraint(条件约束)。新知识学到了吗?欢迎留言。
2020.9.4
https://docs.djangoproject.com/en/3.1/ref/models/constraints/
https://blog.hackajob.co/djangos-new-database-constraints/
Django基础(5): 表单forms的设计与使用
Django ORM Cookbook精选摘录(下) 保持不同模型数据同步更新,使用信号和重写save方法哪个好?
Django基础(22): 数据库的设计之自定义表名,建立索引和使用多数据库主从配置
django
-scopes
我们中的许多人都使用
Django
构建多租户应用程序,每个用户只能访问我们应用程序中一小部分单独的数据,同时具有某些全局功能,这使得每个客户端无法使用单独的
数据库
。 尽管
Django
出色地保护了我们免受构建SQL注入漏洞和类似错误的侵害,但
Django
却无法保护我们免受逻辑错误的侵害,而对于多租户应用程序而言,最危险的安全问题类型之一就是我们会在租户之间泄漏数据。
忘记一个.filter调用很容易,并且在手动和自动测试中都很难捕获到这些错误,因为在开发设置中通常没有很多客户。 除了外,生态系统中没有很多方法可以防止这些错误的发生,除非进行严格的代码审查。
django
-shoogie
Shoogie是一个小型
django
应用程序,用于将异常与
django
的标准HTML调试响应一起记录到
数据库
中的表中。 受启发,它打算成为的轻量级替代品。
自2012年3月起,Shoogie已投入生产。
Shoogie这个名字是希伯来语sh&#
39
;giah (שגיאה)的小写,意思是“错误”。 Shoogie (שוגי)也恰好是以色列流行的儿童糖果点心的名称。 我们希望
django
-shoogie能够使处理服务器错误的体验更加美好。
简单的,针对服务器错误的日志记录
记录
django
熟悉的500技术响应
使用
Django
的标准管理界面
易于按用户,异常,文件,功能进行检索
轻松提取用户的电子邮件地址
日志处理程序在外部事务管理中进行操作
可配置的异常忽略
可配置的回溯过滤
版本兼容性
django
-shoogie与
Django
1.3至1.6
django
-aggtrigg
Django
的自动触发器生成器
创建触发器以进行一些聚合,并允许在不使用COUNT()聚合的情况下对
数据库
中的对象进行计数。 详细的文档位于“ docs”目录中。
将“
django
_aggtrigg”
添加
到您的INSTALLED_APPS设置中,如下所示:
INSTALLED_APPS = (
&#
39
;
django
_aggtrigg&#
39
;,
在模型中导入字段:
from
django
_aggtrigg.models import
Int
egerTriggerField
from
django
_aggtrigg.models import FloatTriggerField
按原样配置您的字段:
class Apple(models.Model):
indice =
Int
egerTriggerField(def
mkvirtualenv -a /path/to/project
django
-hypnos
安装先决条件:
pip install -r requirements/dev.txt
编辑文件/ path /到/ virtualenvs /
django
-hypnos / bin /后激活,并
添加
适应它们的以下几行:
DJANGO
_SETTINGS_MODULE定义我们处于开发模式
DEFAULT_DB对应于
Django
应用程序的
数据库
WEBSERVICE_DB对应于我们要将Web服务连接到的
数据库
export
DJANGO
_SETTINGS_MODULE=hypnos.settings.dev
export DEFAULT_DB_NA
使用
Django
中遇到这样一个需求,对一个表的几个字段做 联合唯一索引,例如学生表中 姓名和班级 2个字段在一起表示一个唯一记录。
Django
中model部分的写法, 参见 unique-together 部分文档。
class MyModel(models.Model):
field1 = models.CharField(max_length=50)
field2 = model...
比如:设计数据表时,要求username字段不允许重复,这时候就需要在CREATE数据表时加入相应的
约束
。再比如注册时候必须填写邮箱、性别等。
约束
的分类按
约束
定义的位置可分
列级
约束
表级
约束
按
约束
的作用可分
主键
约束
PRIMA...
Django
在本月10日发布了
Django
3.0 alpha版本,标志着
Django
3.X时代的来临。作为
Django
的忠粉们,你们准备好了吗? 尽管
Django
3...
背景用
django
自带的admin和auth搭建了内部网站,使用了
django
的用户和权限分组系统,但是在移到生产环境时发现公司把REFERENCES这种命令禁止了,DBA说影响性能不给开权限,所以不得不尝试把外键从db层移到应用层。第一次尝试刚开始只找到https://docs.
django
project.com/en/dev/ref/models/fields/#
django
.db.models
————总目录——前言——框架版本————
======================= 大爽歌作,made by big shuang =======================
参考:https://docs.
django
project.com/en/2.2/ref/models/fields/
三、模型(models)主键外键
梳理自官方文档:automatic-primary-key-fields
不设置主键的情况下,
Django
会自动为每个模型提供以下字段:
id = .