【web系列十一】使用django创建数据库表

news2025/2/25 8:32:22

目录

基本介绍

Model

ORM

创建数据库的流程

安装插件

        安装python中操作MySQL的库,这里用了django官方推荐的mysqlclient

创建数据库

连接数据库

1、工程同名app下的settings.py

2、子应用的models.py

3、子应用中的admin.py

生成数据表

1、更新数据表变化情况

2、生成/更新数据表

详解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 = 'User'

3、子应用中的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_app

2、生成/更新数据表

python manage.py migrate

         这时就可以看到数据库中已经生成了对应的数据表了。

详解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=(
(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 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 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)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/408283.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

element-ui 修改el-form-item样式

文章目录form结构修改el-form-item所有样式只修改label只修改content只修改input只修改buttonform结构 <el-form :model"formData" label-width"80px"><el-form-item label"label1"><el-input v-model"formData.value1&quo…

vue中使用wangEditor以及设置菜单栏

首先安装&#xff0c;我最开始是安装wangEditor v5版本的也就是安装方式是下面两个 npm install wangeditor/editor-for-vue --save npm install wangeditor/editor --save 但是最后跟着官网的视频教程安装好了&#xff0c;不能够运行&#xff0c;提示是&#xff1a;Module par…

antd中的form表单中的wrapperCol和labelCol问题

之前在学这块时候比较模糊 有点不熟 以至于在后来的开发过程中看别人的代码中的xs sm等 以及{span&#xff1a;8}也表示困惑&#xff0c; 但也不敢问大佬&#xff08;怕因为太简单而被嘲讽&#xff09;&#xff0c;只能自己去百度去了解&#xff0c;总算是有些眉目&#xff0c;…

vue xlsx插件导入

首先安装xlsx插件 yarn add xlsx0.15.3安装时候就有一个坑。版本问题第一次安装没有指定版本直接yarn add xlsx&#xff0c;安装的最新版本0.18多&#xff0c;会报XLSX没有read方法&#xff08;读取Excel表格对象的方法&#xff09; 具体代码 <el-upload class"uplo…

uniapp配置网络请求

1.简介 由于平台的限制&#xff0c;小程序项目中不支持 axios&#xff0c;而且原生的 wx.request() API 功能较为简单&#xff0c;不支持拦截器等全局定制的功能。因此&#xff0c;建议在 uni-app 项目中使用 escook/request-miniprogram 第三方包发起网络数据请求。 官方文…

JavaScript常见数组方法,教你如何转置矩阵

&#x1f4dc;个人简介 ⭐️个人主页&#xff1a;微风洋洋&#x1f64b;‍♂️ &#x1f351;博客领域&#xff1a;编程基础,后端 &#x1f345;写作风格&#xff1a;干货,干货,还是tmd的干货 &#x1f338;精选专栏&#xff1a;【JavaScript】 &#x1f680;支持洋锅&#xff…

git提交规范,规范自己的提交标准

为了规范我的git提交内容&#xff0c;提交的时候commit -m “备注的信息”&#xff0c;但是每个人的备注信息千奇百怪&#xff0c;为了统一&#xff0c;我们进行了git的规范。 首先要全局安装commitizen npm i -g commitizen4.2.4然后安装插件 npm i cz-customizable6.3.0…

javascript获取url信息的常见方法

1、获取页面完整的url 1 2 var alocation.href; console.log(a); // “http://www.cnblogs.com/wuxibolgs329/p/5261577.html#flag?test12345” 2、获取页面的域名 var host window.location.host; //www.cnblogs.com var host2 document.domain; //www.cnblogs.com …

学生管理系统Element UI版

&#x1f482; 个人主页: 陶然同学&#x1f91f; 版权: 本文由【陶然同学】原创、在CSDN首发、需要转载请联系博主&#x1f4ac; 如果文章对你有帮助、欢迎关注、点赞、收藏(一键三连)和订阅专栏哦&#x1f485; 想寻找共同成长的小伙伴&#xff0c;请点击【Java全栈开发社区】…

微前端 - qiankun

前言 qiankun 是一个基于 single-spa 的微前端实现库&#xff0c;旨在帮助大家能更简单、无痛的构建一个生产可用微前端架构系统。 本文主要记录下如何接入 qiankun 微前端。主应用使用 vue2&#xff0c;子应用使用 vue3、react。 一、主应用 主应用不限技术栈&#xff0c;只需…

前后端分离式交互

目录 前言 1.javaEE环境安装 第一步&#xff1a;正常创建javase项目 第二步&#xff1a;右击项目&#xff0c;引入框架支持 第三步&#xff1a;将项目部署到Tomcat服务器上。Tomcat安装及配置 2.servlet搭建 请求格式为&#xff1a;ip:端口/项目名/servlet地址 3.servl…

uniapp -- 扫码记录(针对app场景)

背景 扫码需求日益增多&#xff0c;为了满足客户的需求&#xff0c;扫码演变的多种多样&#xff0c;其中有二维码&#xff0c;条形码居中&#xff0c;条形码又可以细分成几种,以下记录全屏和自定义页面扫码的在uniapp的技术实现 全屏扫码 uniapp自身带的api方法-uni.scanCod…

vscode的vue代码提示与补全没反应(vetur问题)

问题&#xff1a;vscode的里面写vue时候代码提示用不了了 问题原因&#xff1a;vetur这个插件升级了&#xff0c;与老版本的vscode不适配了 解决方案&#xff1a; 1.卸载vscode&#xff0c;与vscode官网下载最新版本vscode 2.安装老版本的vetur(感谢评论区另一个大佬推荐的…

刷题日常计~JS③

作者 : SYFStrive 博客首页 : 点击跳转HomePage &#x1f4dc;&#xff1a; 初编程JavaScript之每天10题 &#x1f449; 从质变到量变&#x1f4aa; &#x1f4cc;&#xff1a;个人社区&#xff08;欢迎大佬们加入&#xff09; &#x1f449;&#xff1a;社区链接&#x1f5…

关于WEB-INF目录及Tomcat部署方式、原理的简单理解

个人学习所用&#xff0c;有不足或错误之处欢迎指正和补充&#xff01; 目录 前言&#xff1a; 一、WEB-INF目录与META-INF目录 1. Web应用程序的目录结构 2. WEB-INF简介 3. WEB-INF的作用 4. 静态资源的访问 二、Tomcat部署本地工件 1. war和war exploded的区别 2.…

【HTML小游戏】推箱子网页版(附完整源码)

最近刚刚更新完了HTML,CSS的万字总结,有很多人已经学习完了文章,感觉反馈还不错,今天,用HTML,CSS,JS的知识编写了一个童年经典游戏 - 推箱子,供学习参考。 文章目录 1. 效果展示2. 游戏介绍3. 游戏规则4. 源码学习1. 效果展示 游戏主界面展示: 游戏界面展示: 2. 游戏…

ECMAScript6新特性【数组扩展(扩展运算符、新增方法一、新增方法二、新增方法三)】(四)-全面详解(学习总结---从入门到深化)

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是小童&#xff0c;Java开发工程师&#xff0c;CSDN博客博主&#xff0c;Java领域新星创作者 &#x1f4d5;系列专栏&#xff1a;前端、Java、Java中间件大全、微信小程序、微信支付、若依框架、Spring全家桶 &#x1f4…

【vue2】vuex的安装、配置与使用

一、前言 使用vuex可以实现数据的共享。 二、安装 vscode中新建终端安装vuex。由于vue2不能使用vuex4的版本&#xff0c;所以在安装时需要指定版本3 npm i vuex3 三、vuex工作流 vuex核心包括actions、mutations、state。 ①state用来存储数据&#xff1b; ②actions用…

vue+element-ui

一.使用图形化界面&#xff0c;创建vue项目 vue ui(在根目录下&#xff0c;打开cmd,启动图形化界面) 添加插件 添加element-ui插件 这里选择import on demand 安装好了 添加依赖 添加axios依赖 添加好了 二.创建Git仓库&#xff0c;连接并上传刚刚创建的项目 在项目文件目录下…

基于微信小程序的电影订票系统设计与实现(代码+数据库+论文)

项目简介 本系统是基于微信小程序的电影订票系统的设计与实现。基于B/S架构模式进行设计&#xff0c;使用了JavaScript、CSS、java语言等&#xff0c;后台数据库设计使用Mysql。本电影订票系统主要分为前端小程序订票系统和后台电影管理两部分。用户使用时接触的是系统前端小程…