django创建项目命令(【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 models class 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 = User3、子应用中的admin.py
如果熟练使用Mysql或SQLyog这类可视化工具操作数据库的话,这步可以省略
from django.contrib import admin from . import models admin.site.register(models.User)这里不介绍如何使用admin管理数据库 ,想了解的可以看这篇文章 。
django的admin组件使用详解_Dream_it_possible!的博客-CSDN博客_admin django
生成数据表
1 、更新数据表变化情况
python manage.py makemigrations main_app2 、生成/更新数据表
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_delete None # 关联的数据同时删除 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=( (uM, uMale), (uF, uFemale), ) 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 Test def testdb(request): test1 = Test(name=runoob) test1.save() return HttpResponse("<p>数据添加成功!</p>")获取数据
from django.http import HttpResponse from TestModel.models import Test def testdb(request): # 初始化 response = "" response1 = "" # 通过objects这个模型管理器的all()获得所有数据行 ,相当于SQL中的SELECT * FROM list = 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 = response1 return HttpResponse("<p>" + response + "</p>")更新数据
from django.http import HttpResponse from TestModel.models import Test def testdb(request): # 修改其中一个id=1的name字段 ,再save ,相当于SQL中的UPDATE test1 = 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中的UPDATE test1 = 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 Test def 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 cant 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 bbs6 、同步数据库
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博客
创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!