Django项目如何给数据库添加约束

只要你的Web开发知识不是语文老师教的,那么你应该已经知道一个合格的开发者应该永远抱着怀疑的眼光看用户提交的数据。你不仅需要在前端通过表单或其它方式进行验证,还需要在后台视图拿到用户发送的数据后再对其进行验证一遍。假如有一天你开发一个少儿不宜的网站,你的用户模型里有年龄(age)这个字段而你要求每个注册用户年龄都大于18岁,在Django中你当然可以自定义表单的clean方法, 自定义validators或者重写模型的save方法对年龄字段进行验证。然而你想过没有一件事没有?这能阻止某个员工或用户通过Django的admin后台或数据库可视化工具对数据库进行修改,把用户的年龄修改到18岁以下吗?当然不能。

划重点:前后端的数据验证并不能保证数据库里数据的正确性和有效性,在数据库层面添加一些约束条件是最根本的解决方法。

今天我们就来看下如何在Django项目中给数据库添加约束(Constraints)。

什么是数据库约束(db constraints)基本常识

数据库约束(Contraints)是在数据库层面对表中的数据进行进一步的限制, 保证数据的正确性、有效性和完整性(data integrity)。 约束通常与一个表相关联,并使用CREATE CONSTRAINT或CREATE ASSERTION SQL语句创建。他们定义数据库中的数据必须符合的某些属性。他们可以应用于列,整个表格,多个表格或整个模式。

常见的约束条件有:

  • not null - 列中的每个值都不能为NULL
  • primary key - 指定列中的值对于表中的每一行必须是唯一的,而不是NULL ;
  • unique - 对于表中的每一行必须是唯一的
  • check - 指定一个表达式,为了满足约束条件,它必须计算为真

在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(条件约束)。新知识学到了吗?欢迎留言。

以上就是Django项目如何给数据库添加约束的详细内容,更多关于Django 给数据库添加约束的资料请关注我们其它相关文章!

(0)

相关推荐

  • Python的Django框架实现数据库查询(不返回QuerySet的方法)

    一.创建模型类: # -*- coding: utf-8 -*- from __future__ import unicode_literals from django.db import models class Course(models.Model): """课程表""" name = models.CharField(verbose_name='课程名称', max_length=255) description = models.Tex

  • pycharm中django框架连接mysql数据库的方法

    1.首先下载安装pymysql模块. pip install pymysql 如果出现 timeout 超时可以使用其他的资源下载: pip install 模块名 -i https://pypi.douban.com/simple 2.导入库 在项目的init文件中编写下列代码: # 导入pymysql模块 import pymysql pymysql.install_as_MySQLdb() 这样整个项目都能使用pymysql,就不用再每个文件都导入pymyqsl 3.在seeting.py

  • django 解决model中类写不到数据库中,数据库无此字段的问题

    如果你遇到了这个错误–MySQL Strict Mode is not set for database connection 'default' 还有这种错误,models中的代码 为什么会出现这种错误呢?有两种可能,一种settings少了options,一中是你的models文件中加了逗号 第一种可能 settings中需要添加以下字段 DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'mxs

  • django inspectdb 操作已有数据库数据的使用步骤

    inspectdb使用步骤 1.配置项目setting文件 2.配置项目__init__.py 使用pymysql连接数据库 import pymysql pymysql.version_info = (1, 20, 23) pymysql.install_as_MySQLdb() 3.在terminal中执行语句 python manage.py inspectdb > [your app name]\models.py 4.执行迁移 python manage.py makemigratio

  • Django连接本地mysql数据库(pycharm)的步骤

    第一步:更改setting.py中的DATABASES # 配置数据库 DATABASES = { 'default': { # python自带的一个数据库,基本不会被使用 # 'ENGINE': 'django.db.backends.sqlite3', # 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), # 注册我们自己使用的数据库连接 'ENGINE': 'django.db.backends.mysql', # 数据库引擎 'NAME': '

  • django 数据库返回queryset实现封装为字典

    默认情况下,Python DB API会返回不带字段的结果,这意味着你得到的是一个列表,而不是一个字典.花费一点性能代价之后,你可以返回一个字典形式的结果,像这样: def dictfetchall(cursor): "Returns all rows from a cursor as a dict" desc = cursor.description return [ dict(zip([col[0] for col in desc], row)) for row in cursor

  • Python web框架(django,flask)实现mysql数据库读写分离的示例

    读写分离,顾名思义,我们可以把读和写两个操作分开,减轻数据的访问压力,解决高并发的问题. 那么我们今天就Python两大框架来做这个读写分离的操作. 1.Django框架实现读写分离 Django做读写分离非常的简单,直接在settings.py中把从机加入到数据库的配置文件中就可以了. DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'HOST': '127.0.0.1', # 主服务器的运行ip 'PORT':

  • Django ForeignKey与数据库的FOREIGN KEY约束详解

    数据库在高并发的场景下使用外键约束会有锁问题并且使用外键会增加运维成本,所以很多公司都规定生产环境的数据库禁止使用外键. 那么不使用外键约束的情况下使用 Django ORM 如何实现关联查询两个表呢?这曾是困扰我很久的一个问题,今天终于找到了答案,写出来分享一下. Django 的 ForeignKey 和数据库的 FOREIGN KEY 并不一样.Django 的 ForeignKey 是一种逻辑上的两个表的关联关系,可以指定是否使用数据库的 FOREIGN KEY 约束. 在开头提到的场景

  • django使用多个数据库的方法实例

    通过官方文档https://docs.djangoproject.com/zh-hans/3.1/topics/db/multi-db/和csdnhttps://blog.csdn.net/songfreeman/article/details/70229839的这两篇文章可以进行多数据库的设置.但是设置后可能会出现问题,由于我连接的数据库是通过inspactdb的方法得到的model.于是在migrate的时候出现了问题,会提示 1146, "Table xxx doesn't exist&q

  • Django项目如何给数据库添加约束

    只要你的Web开发知识不是语文老师教的,那么你应该已经知道一个合格的开发者应该永远抱着怀疑的眼光看用户提交的数据.你不仅需要在前端通过表单或其它方式进行验证,还需要在后台视图拿到用户发送的数据后再对其进行验证一遍.假如有一天你开发一个少儿不宜的网站,你的用户模型里有年龄(age)这个字段而你要求每个注册用户年龄都大于18岁,在Django中你当然可以自定义表单的clean方法, 自定义validators或者重写模型的save方法对年龄字段进行验证.然而你想过没有一件事没有?这能阻止某个员工或用

  • Oracle如何给数据库添加约束过程解析

    主键约束(两个特性) 1:主键必须写 2:主键不可重复 create table stu01( sid varchar(100), sname varchar2(100) --constraint PK_stu01_sid primary key (sid) ) --添加约束(主键) alter table stu01 add constraint PK_stu01_sid primary key(sid) ---添加主键约束 alter table stu01 drop constraint

  • Django项目中添加ldap登陆认证功能的实现

    最近在开发一个Django项目过程中,碰到了通过ldap认证用户登录的需求.由于之前都是自己写密码加密.用户登录等逻辑,连Django自带的认证模块都没用过,无奈网上关于django配置ldp的资料实在不全.因此,自己摸索了一种简单的实现方式,记录于此. 开发环境 Centos7.2下安装pycharm,并通过X转发至Winodws桌面进行开发 安装pyenv,使用virtualenv 3.6.2 Archives 安装开发过程中需要用到的第三方库,django, mysqlclient等等..

  • Django项目优化数据库操作总结

    目录 合理的创建索引 设置数据库持久连接 减少SQL的执行次数 仅获取需要的字段数据 使用批量创建.更新和删除,不随意对结果排序 参考网址:Django官方数据库优化 使用 QuerySet.explain() 来了解你的数据库是如何执行特定的 QuerySet 的. 你可能还想使用一个外部项目,比如 django-debug-toolbar ,或者一个直接监控数据库的工具. 合理的创建索引 索引可能有助于加快查询速度,但是也要注意索引会占用磁盘空间,创建不必要的索引只会形成浪费.数据库表中的主

  • Django项目配置连接多个数据库的方法记录

    一个APP对应一个默认数据库,若连接其他数据库用".using()" Author.objects.using('db02').all() 1.在项目settings中增加数据库配置 # settings.py DATABASES = { 'default': { 'ENGINE': 'django.db.backends.oracle', 'NAME': 'orcl19c', 'USER': "username01", 'PASSWORD': "pass

  • Python之Web框架Django项目搭建全过程

    Python之Web框架Django项目搭建全过程 IDE说明: Win7系统 Python:3.5 Django:1.10 Pymysql:0.7.10 Mysql:5.5 注:可通过pip freeze查看已安装库版本信息. Django 是由 Python 开发的一个免费的开源网站框架,可以用于快速搭建高性能,优雅的网站! Django 特点 强大的数据库功能 用python的类继承,几行代码就可以拥有一个丰富,动态的数据库操作接口(API),如果需要你也能执行SQL语句. 自带的强大的后

  • Django基于ORM操作数据库的方法详解

    本文实例讲述了Django基于ORM操作数据库的方法.分享给大家供大家参考,具体如下: 1.配置数据库 vim settings #HelloWorld/HelloWorld目录下 DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', #mysql数据库中第一个库test 'NAME': 'test', 'USER': 'root', 'PASSWORD': '123456', 'HOST':'127.0.0.1', '

  • Django项目实战之用户头像上传与访问的示例

    1 将文件保存到服务器本地 upload.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> </head> <body> <form action="" method="post" enctype="multipart/form-data">

  • 创建Django项目图文实例详解

    本文实例讲述了创建Django项目的方法.分享给大家供大家参考,具体如下: 创建Django项目 创建一个HelloDjango项目 GitHub地址:https://github.com/liangdongchang/HelloDjango.git 1.在linux命令窗口终端下 创建Django项目 django-admin.py startproject HelloDjango sudo apt install tree tree HelloDjango/ 2.在PyCharm中创建 fi

  • Django项目使用CircleCI的方法示例

    自从认识了 CircleCI之后,基本上都在用这个了.相比于之前用的travis-ci,CircleCI 丑是丑了点,但是相比与 travis 有几点好处: CircleCI 基于 docker image 的,怎么做隔离的不太清楚,有可能是在虚拟机上面执行 docker 来做隔离的,而 travis 还是基于 VM.这样好的好处是,CircleCI 提供了很多 image,你可以组合出来很多服务.比如 Django 项目用到了 redis 和 MySQL,你只要在 yaml 里面加上这两个 i

随机推荐