【web系列十一】使用django创建数据库表
目录
基本介绍
Model
ORM
创建数据库的流程
安装插件
安装python中操作MySQL的库,这里用了django官方推荐的mysqlclient
创建数据库
连接数据库
1、工程同名app下的settings.py
2、子应用的models.py
3、子应用中的admin.py
生成数据表
1、更新数据表变化情况
2、生成/更新数据表
3、版本回退
详解Model语法
字段定义
外键参数
其他一些参数的含义
数据库操作
添加数据
获取数据
更新数据
更新包含外键的数据
删除数据
更新数据表结构
方法1:先删除再重构
方法2:新增字段可以直接在原结构上添加
问题记录
django中获取的当前时间被保存到mysql数据库中会有时差
方案一:修改settings.py文件
方案二:修改数据库文件
参考资料
这篇文章主要介绍django中model模块的常用字段、参数,以及如何操作数据库。
基本介绍
Model
Django 对各种数据库提供了很好的支持,包括:PostgreSQL、MySQL、SQLite、Oracle。
Django 为这些数据库提供了统一的调用API。 我们可以根据自己业务需求选择不同的数据库。
MySQL 是 Web 应用中最常用的数据库。本文将以 MySQL作为实例进行介绍。
对MySQL还不太了解的可以通过博主的这两篇文章学习。
【web系列九】快速上手MySQL数据库_Nicholson07的博客-CSDN博客
【web系列十】Vue3+Django+MySQL搭建前后端框架_Nicholson07的博客-CSDN博客
ORM
Django 模型使用自带的 ORM。
对象关系映射(Object Relational Mapping,简称 ORM )用于实现面向对象编程语言里不同类型系统的数据之间的转换。
ORM 在业务逻辑层和数据库层之间充当了桥梁的作用。
ORM 是通过使用描述对象和数据库之间的映射的元数据,将程序中的对象自动持久化到数据库中。
使用 ORM 的好处:
- 提高开发效率。
- 不同数据库可以平滑切换。
使用 ORM 的缺点:
- ORM 代码转换为 SQL 语句时,需要花费一定的时间,执行效率会有所降低。
- 长期写 ORM 代码,会降低编写 SQL 语句的能力。
ORM 解析过程:
- 1、ORM 会将 Python 代码转成为 SQL 语句。
- 2、SQL 语句通过 pymysql 传送到数据库服务端。
- 3、在数据库中执行 SQL 语句并将结果返回。
ORM 对应关系表:
创建数据库的流程
安装插件
安装python中操作MySQL的库,这里用了django官方推荐的mysqlclient
pip install mysqlclient
创建数据库
使用mysqlclient无法创建数据库,只能和现有的数据库关联,因此首先要在MySQL中船舰好数据库。
可以直接再mysql命令行中用create创建,也可以用类似SQLyog等可视化工具创建。
这里创建了一个test数据库。
连接数据库
1、工程同名app下的settings.py
DATABASES = {'default': {'ENGINE': 'django.db.backends.mysql','NAME': 'test','USER': 'root','PASSWORD': 'hirain123','HOST': 'localhost','PORT': '3306','OPTION'; {'init_command': 'SET sql_model="STRICT_TRANS_TABLES"',}}
}
2、子应用的models.py
from django.db import modelsclass User(models.Model):id = models.AutoField(primary_key=True)name = models.CharField(max_length=50)level = models.IntegerField(default=1)createTime = models.DateTimeField(null=True)class Meta:db_table = 'User'
3、子应用中的admin.py
如果熟练使用Mysql或SQLyog这类可视化工具操作数据库的话,这步可以省略
from django.contrib import admin
from . import modelsadmin.site.register(models.User)
这里不介绍如何使用admin管理数据库,想了解的可以看这篇文章。
django的admin组件使用详解_Dream_it_possible!的博客-CSDN博客_admin django
生成数据表
1、更新数据表变化情况
python manage.py makemigrations main_app
2、生成/更新数据表
python manage.py migrate
这时就可以看到数据库中已经生成了对应的数据表了。
3、版本回退
python manage.py migrate app_name migrations_version// python manage.py migrate main_app 0018_auto_20230401_2321
执行成功后数据库中的对应的更新就小时了,然后记得手动删除多余的migrations版本文件。
详解Model语法
字段定义
## 地址
# varchar
# 正则表达式邮箱,继承CharField
v = models.EmailField([max_length=75, **options])# varchar
# 地址正则表达式,继承CharField
v = models.URLField([verify_exists=True, max_length=200, **options]) # varchar
# ip4正则表达式
v = models.IPAddressField([**options])# varchar
v = models.GenericIPAddressField## 时间
# datetime
# auto_now=True每次更新都会更新这个时间
# auto_now_add=True自动记录创建时间
v = models.DateField([auto_now=True,auto_now_add=True, **options])# datetime
# 继承DateField
v = models.DateTimeField([auto_now=True,auto_now_add=True, **options])# time
# 时间 HH:MM[:ss[.uuuuuu]]
v = models.TimeField([auto_now=False, auto_now_add=False, **options])## 数字
# double
v = models.FloatField([**options])# 小整型(-32768,32767)
v = models.SmallIntegerField([**options])# int
# 整型(-2147483648,2147483647)
v = models.IntegerField([**options])# 长整型(-9223372036854775808,9223372036854775807)
v = models.BigIntegerField([**options])# 正小整型(0,32767)
v = models.PositiveSmallIntegerField([**options])# 正整型(0,2147483647)
v = models.PositiveIntegerField([**options])## 布尔
# boolean或bit
# 不允许为null
v = models.BooleanField([**options]) # boolean或bit
# 允许为null
v = models.NullBooleanField([**options])# bit
v = models.BinaryField([**options]) # decimal
# 十进制小数类型,必须指定整数位max_digits和小数位decimal_places
v = models.DecimalField(max_digits=None, decimal_places=None[, **options]) ## 字符串
# varchar
# 必须设置max_length
v = models.CharField(max_length=None[, **options]) # varchar
# 用逗号分割的数字
# 继承CharField,所以必须设置max_length
v = models.ComaSeparatedIntegerField(max_length=None[, **options])## 文件
# varchar
# upload_to指定保存目录可带格式
v = models.FileField(upload_to=None[, max_length=100, **options]) # varchar
v = models.FilePathField(path=None[, match=None, recursive=False, max_length=100, **options])# 继承FileField
v = models.ImageField(upload_to=None[, height_field=None, width_field=None, max_length=100, **options])# text
v = models.TextField([**options]) # text
v = models.XMLField(schema_path=None[, **options]) ## 其他
# 自增
# 如果没有的话,默认会生成一个名称为 id 的列
# 如果要显示的自定义一个自增列,必须将给列设置为主键 primary_key=True。
v = models.AutoField([**options]) # varchar
# 标签,内含索引,减号、下划线、字母、数字
v = models.SlugField([max_length=50, **options])# 外键,关联其它模型,创建关联索引
v = models.ForeignKey(othermodel, on_delete=None[, **options])# 一对一
# 字段关联表属性
v = models.OneToOneField(othermodel[, parent_link=False, **options])# 多对多
# 关联其它模型,创建关联表
v = models.ManyToManyField(othermodel[, **options])
外键参数
#on_deleteNone # 关联的数据同时删除models.CASCADE # 与None类似,默认删除models.DO_NOTHING # 什么都不做,不报错models.PROTECT # 阻止删除,并触发ProtectError报错models.SET_NULL # 设置当前表关联数据的值为null(必须支持null,即null参数为True)models.SET_DEFAULT # 设置当前关联数据的值为default(必须定义了default)models.SET(a) # 设置当前关联数据的值为a(a为一个具体的值或者一个全局可调用的回调函数)
其他一些参数的含义
null=True # 数据库中字段是否可以为空primary_key=False # 主键,对AutoField设置主键后,就会代替原来的自增 id 列auto_now=True # 自动创建---无论添加或修改,都是当前操作的时间auto_now_add # 自动创建---永远是创建时的时间# 选择项
GENDER_CHOICE=(
(u'M', u'Male'),
(u'F', u'Female'),
)
choices=GENDER_CHOICE
e.g.:gender = models.CharField(max_length=2,)max_length=100 # 最大长度default # 默认值verbose_name # admin中字段显示的名称name|db_column # 数据库中字段的名称unique=True # 不允许重复db_index=True # 数据库索引error_messages=None # 错图提示auto_created=False # 自动创建blank=True # 从django的Admin中添加数据时是否可允许空值editable=True # 在admin中是否可编辑help_text # 在admin中提示帮助信息
数据库操作
添加数据
from django.http import HttpResponse
from TestModel.models import Testdef testdb(request):test1 = Test(name='runoob')test1.save()return HttpResponse("<p>数据添加成功!</p>")
获取数据
from django.http import HttpResponse
from TestModel.models import Testdef testdb(request):# 初始化response = ""response1 = ""# 通过objects这个模型管理器的all()获得所有数据行,相当于SQL中的SELECT * FROMlist = Test.objects.all()# filter相当于SQL中的WHERE,可设置条件过滤结果response2 = Test.objects.filter(id=1) # 获取单个对象response3 = Test.objects.get(id=1) # 限制返回的数据 相当于 SQL 中的 OFFSET 0 LIMIT 2;Test.objects.order_by('name')[0:2]#数据排序Test.objects.order_by("id")# 上面的方法可以连锁使用Test.objects.filter(name="runoob").order_by("id")# 输出所有数据for var in list:response1 += var.name + " "response = response1return HttpResponse("<p>" + response + "</p>")
更新数据
from django.http import HttpResponse
from TestModel.models import Testdef testdb(request):# 修改其中一个id=1的name字段,再save,相当于SQL中的UPDATEtest1 = Test.objects.get(id=1)test1.name = 'Google'test1.save()# 另外一种方式#Test.objects.filter(id=1).update(name='Google')# 修改所有的列# Test.objects.all().update(name='Google')return HttpResponse("<p>修改成功</p>")
更新包含外键的数据
from django.http import HttpResponse
from TestModel.models import Test# class User(models.Model):
# create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
# update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间')
# username = models.CharField(max_length=255, unique=True, verbose_name='用户名')
# is_active = models.BooleanField(default=False, verbose_name='激活状态')
# role = models.ForeignKey(Role, on_delete=models.CASCADE, null=True, verbose_name='角色')def testdb(request):# 修改其中一个id=1的name字段,再save,相当于SQL中的UPDATEtest1 = Test.objects.get(id=1)test1.role = Role.objects.get(id=3)test1.save()# test1 = Test.objects.get(id=1)# test1.__dict__.update(**{'username':'nick','role_id':2})# test1.save()# 另外一些方式# Test.objects.filter(id=1).update(role=2)# Test.objects.filter(id=1).update(**{'username':'nick','role':3})# _role = Role.objects.get(id=2)# Test.objects.filter(id=1).update(role=_role)# _role = Role.objects.get(id=1)# Test.objects.filter(id=1).update(**{'username':'nick','role':_role})# 修改所有的列# Test.objects.all().update(name='Google')return HttpResponse("<p>修改成功</p>")
删除数据
from django.http import HttpResponse
from TestModel.models import Testdef testdb(request):# 删除id=1的数据test1 = Test.objects.get(id=1)test1.delete()# 另外一种方式# Test.objects.filter(id=1).delete()# 删除所有数据# Test.objects.all().delete()return HttpResponse("<p>删除成功</p>")
更新数据表结构
有时候在我们使用Django设计了models中的数据库结构,并且已经同步了数据库之后,我们突然想在数据表中更新或者增加新的字段,也就是需要修改数据库的结构,会出现以下的问题:
You are trying to add a non-nullable field 'grade' to student without a default; we can't do that (the database needs something to populate existing rows).
Please select a fix:
1) Provide a one-off default now (will be set on all existing rows with a null value for this column)
2) Quit, and let me add a default in models.py
Select an option:
就是在我们在models中修改了表的字段后,进行python manage.py makemigrations同步数据库时会出现上面报错,会导致数据库结构更新失败。
方法1:先删除再重构
1、删除数据库对应的数据表
注意:在这里可以不用暴力删除数据表,可以利用django的migrations进行,操作如下:
1.1、首先将自己需要重构的数据表类的models注释掉,然后输入命令python manage.py makemigrations,这个时候migration会自动记录删除数据表的操作
1.2、然后在输入命令python manage.py migrate,Django会自动将本地对应的数据库进行删除
2、删除应用当中的migrations文件
3、删除应用当中的pychace文件
4、删除db_sqllite文件(若配置数据库为mysql时,可以删除db_sqllite)
5、建立一个空数据库,命令为python manage.py makemigrations --empty 应用名称
python manage.py makemigrations --empty bbs
6、同步数据库
python manage.py makemigrations
python manage.py migrate
方法2:新增字段可以直接在原结构上添加
#出版社
class Publisher(models.Model):'''出版社数据表'''id=models.AutoField(primary_key=True) #自增ID主键name=models.CharField(max_length=50,verbose_name='出版社名称',null=False,unique=True)def __str__(self):return '{},{}'.format(self.id,self.name)
接下来我们需要新增一个字段addr地址
#出版社
class Publisher(models.Model):'''出版社数据表'''id=models.AutoField(primary_key=True) #自增ID主键name=models.CharField(max_length=50,verbose_name='出版社名称',null=False,unique=True)addr=models.CharField(max_length=128,verbose_name='出版社地址')def __str__(self):return '{},{}'.format(self.id,self.name,self.addr)
由于我们的数据库的Publisher表本身已经有数据了,所以我们在进行python manage.py makemigrations会报错。我们可以在models中加上默认值,在进行makemigrations,这次就会更新成功了!
#出版社
class Publisher(models.Model):'''出版社数据表'''id=models.AutoField(primary_key=True) #自增ID主键name=models.CharField(max_length=50,verbose_name='出版社名称',null=False,unique=True)addr=models.CharField(max_length=128,verbose_name='出版社地址',default='成都市动物园')def __str__(self):return '{},{}'.format(self.id,self.name,self.addr)
问题记录
django中获取的当前时间被保存到mysql数据库中会有时差
这时由于django中获取的是本地时间,而保存到数据库中会转换成utc时间,所以有时差,一般有两种解决方式。
方案一:修改settings.py文件
修改如下:
TIME_ZONE = 'Asia/Shanghai' # 根据你所处的时区修改USE_TZ = False # 从true改为false
方案二:修改数据库文件
进入你的数据库,执行如下命令,查看当前时间
select current_time;
修改时区:
SET GLOBAL time_zone = '+8:00';
这样修改,mysql重启会失效,写入mysql配置文件,配置文件位置如下:
- Linux中: /etc/my.cnf
- windows中: C:\ProgramData\MySQL\MySQLServer (版本号)\my.ini
添加
default-time-zone='+8:00'
参考资料
Django 模型 | 菜鸟教程 (runoob.com)
django的admin组件使用详解_Dream_it_possible!的博客-CSDN博客_admin django
Django更新models数据库结构步骤_Python-考高分网 (kaotop.com)
Django2.2中迁移(makemigrations和migrate)的原理和撤销回退操作图文详解_django的数据库迁移命令的原理_T型人小付的博客-CSDN博客
【web系列十一】使用django创建数据库表相关推荐
- Django——创建数据库和表
Django--创建数据库和表 Django拥有内置的ORM框架(object relational mapping),通过对象操作数据库. 模型是项目的数据来源,其中每一个模型都是一个python类 ...
- 【超详细Django网站开发过程2】便利店管理系统之——创建数据库→定义数据库表→创建数据库表
假装自己拥有一家小便利店,名叫--7-Twelve,我希望制作一个便利店管理系统对我的顾客.销售人员.货物等数据进行管理,先不管前端,后端总免不了对数据的一顿操作,那如何在Django中对数据库进行增 ...
- python代码创建数据库_如何使用python ORM创建数据库表?
首先同大家说了语言的全方面知识,基本上各个位置点都有涉及,不知道大家有没有学到知识点呢?小编还是习惯跟大家说个总结,这样大家才能抓住重点,今天继续来学习下关于Django框架中ORM的使用,主要的作用 ...
- 0基础能学mysql数据库吗_mysql学习入门:零基础如何使用mysql创建数据库表?
零基础如何自学Mysql创建数据库,是Mysql学习者必经之路,Mysql是受欢迎的关系数据库管理系统,WEB应用方面MySQL是很好的RDBMS应用软件之一.如何使用Mysql创建数据库表,打开My ...
- jPA自动创建数据库表的一些配置
2019独角兽企业重金招聘Python工程师标准>>> jPA自动创建数据库表的一些配置 hibernate.cfg.xml 中hibernate.hbm2ddl.auto配置节点如 ...
- centos中用MySQL创建新表_CentOS下使用Shell批量创建数据库表
本文继续探索关于Shell和MySQL的结合使用,我不知道当一个数据库设计完成之后如何快速的创建设计好的数据库表和添加相应基本数据,我目前知道的就是使用Shell和SQL脚本来达到我的目的--快速的. ...
- 使用PowerDesigner创建数据库表
使用PowerDesigner 建数据库表. 一直很忙,没有时间写东西.这次搞点会声会色的,嘿嘿 此技能为项目经理必备技能. 本次主角: 1.在workspace下建立一项目: physical da ...
- 使用程序创建数据库表
使用程序来创建数据库表.
- MySQL(一)——安装、创建数据库表、DML语言
文章目录 1. 简述 2. 安装教程 3. 操作数据库 3.1 操作数据库的基本命令 3.2 数据库的列类型 3.3 数据库的字段属性(重点) 3.4 创建数据库表(重点) 3.5 数据表的类型 3. ...
最新文章
- 使用GZIPInputStream和GZIPOutputStream压缩、解压java对象
- java算法之冒泡排序法
- 网站数据库服务器怎么启动,启动数据库服务器
- c 求最小公倍数_公务员备考-最小公倍数和最小公约数问题
- SAP UI5 bindProperty的实现
- 灾难 BZOJ 2815
- [转]notepad++各种插件
- 吴恩达深度学习3.2笔记_Structuring Machine Learning Projects_机器学习策略(2)
- Excel中 使用链接 批量导入图片
- config.o:文件无法辨识_HAZOP有哪些局限性,及系统生命周期不同阶段的危险辨识...
- 9.1.4 前端 - HTML body标签 - 标题,段落,分割线,换行,特殊符号,列表,超链接,图片,div/span,表格,表单,input标签,多行文本,单选/多选,下拉,按钮...
- linux VM命令下查找
- 句法分析 依存句法分析
- CodeForces 961G Partitions 题解
- 易飞8无销售报价的BOM成本参考
- Flatty Shadow图标自动产生器——在线生成各种扁平化 ICON
- 如何在安装 Enscape渲染器时禁用或启用弹出窗口
- Shell ifs 用法
- 东大18秋计算机网络在线作业1答案,东大18秋学期《计算机辅助数控编程》在线作业1辅导资料...
- 抖音关键词排名怎么靠前,抖音关键词怎么优化?
热门文章
- 黑龙江第三方软件测试机构 CMA/CNAS双资质
- 2021最新最全前端面试题(包含HTML、CSS、JavaScript、Vue、React、浏览器、算法与数据结构等)
- smss.exe之wom毒
- python 实现单链表 Lined List
- 【C++】操作符重载
- golang坑之 'godoc' 不是内部或外部命令,...
- 计算机控制门禁,实验室智能门禁管理系统
- Linux——samba服务器部署
- QIIME2-傻瓜式安装
- Elasticsearch集群“脑裂”现象