【笔记】Django项目中连接Mysql

前言

Django项目中连接Mysql学习笔记

下载依赖

  • 安装Mysql驱动
1
pip install pymysql

修改全局配置

  • 将全局配置中的DATABASES配置,将默认的sqlite3的配置改为mysql的配置

ENGINE:数据库类型
HOST:访问地址,留空默认为127.0.0.1
PORT:端口号
USER:登录用户名
PASSWORD:登录密码
NAME:需要连接的数据库名

<project_name>/<project_name>/settings.py
1
2
3
4
5
6
7
8
9
10
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'HOST': '',
'PORT': '3306',
'USER': '',
'PASSWORD': '',
'NAME': '',
}
}

初始化Mysql驱动

<project_name>/<project_name>/__init__.py
1
2
3
import pymysql

pymysql.install_as_MySQLdb()

表结构的创建与修改

在Module添加一个Mysql数据表映射

  • 通过Python类映射为Mysql数据表
    • <app__name>_类名映射为Mysql数据表名
    • 类中定义的变量映射为Mysql数据表中的字段

字段类型

CharField:字符串类型
TextField:文本类型
EmailField:邮箱格式字符串
UrlField:网址格式字符串
BooleanField:布尔类型
NullBooleanField:可为空的布尔类型
IntegerField:整型,取值范围[-2147483648,2147483647]
SmallIntegerField:短整型[-32768,32767]
BigIntegerField:长整型
PositiveIntegerField:正整型,取值范围[0,2147483647]
PositiveSmallIntegerField:短正整型,取值范围[0,32767]
FloatField:浮点型
DecimalField:十进制小数
DateField:日期类型,形如YYYY-MM-DD
DateTimeField:日期时间类型,形如YYYY-MM-DD hh:mm:ss
TimeField:时间类型,形如hh:mm:ss
ImageField:图片类型,用于存储图片格式文件
FileField:文件类型,用于存储任意格式文件

属性

作用于DecimalField字段类型的属性

max_digits=<num>:数字中允许的最大位数
decimal_places=<num>:存储的十进制位数

作用于ImageField字段类型的属性

width_field=<num>:图片宽度
height_field=<num>:图片高度

作用于ImageFieldFileField字段类型的属性

upload_to=<src>:文件上传时的本地路径

作用于DateFieldDateTimeFieldTimeField字段类型的属性

auto_now:自动添加当前时间作为默认值
auto_now_add:自动在首次创建时添加当前时间作为默认值

作用于任何字段类型的属性

blank=True:是否可为空值
null=True:是否可将值设置为null,通常只是为了配合on_delete属性
primary=True:是否为主键
max_length=<num>:最大长度
default=<value>:默认值
verbose_name=<name>:后台管理系统admin显示的名字
db_column=<name>:数据库字段名
unique=True:是否为唯一索引,唯一索引不允许重复
db_index=True:是否为普通索引,普通索引允许重复

<project_name>/<app_name>/models.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from django.db import models

class User(models.Model):
id如果没有指定会自动生成
name = models.CharField(max_length=5, blank=False)
age = models.SmallIntegerField(default=0)
phone = models.CharField(max_length=11, db_index=True, blank=True, default='')
email = models.EmailField(blank=True, default='')
info = models.TextField()
create_time = models.DateTimeField(auto_now_add=True)
update_time = models.DateTimeField(auto_now=True)
定义唯一联合索引,唯一索引不允许重复
unique.together = []
定义普通联合索引,普通索引允许重复
index.together = []

定义联合索引

<project_name>/<app_name>/models.py
1
2
3
4
5
6
7
8
9
10
from django.db import models

class User(models.Model):
id如果没有指定会自动生成
name = models.CharField(max_length=5, blank=False)
age = models.SmallIntegerField(default=0)
phone = models.SmallIntegerField(db_index=True, blank=True, default='')
定义联合索引
class Meta:
index_together = ['name', 'phone']

多表关联字段

relate_name="":自定义当前字段的名称,如果不指定默认使用Python变量名作为字段名

<project_name>/<app_name>/models.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from django.db import models

class User(models.Model):
id = model.IntegerField(primary=True)
name = models.CharField(max_length=5, blank=False)

class OneToOne(model.Model):
id = model.IntegerField(primary=True)
user = model.OneToOneField(User, blank=True, null=True, on_delete=models.SET_NULL)

class OneToMany(model.Model):
id = model.IntegerField(primary=True)
user = model.ForeignKey(User, relate_name="user", blank=True, null=True, on_delete=models.SET_NULL)

class MonyToMont(model.Model):
id = model.IntegerField(primary=True)
user = model.ManyToManyField(User, relate_name="user")

更新Mysql数据表结构

  1. 生成脚本:在定义完映射后,执行python manage.py makemigrations命令,会在<project_name>/<app_name>/migrations目录下生成用于更新Mysql数据库的Python文件
  2. 数据库迁移:在生成用于更新Mysql数据库的Python文件后,执行python manage.py migrate命令,会立即根据生成的Python文件更新Mysql数据表结构

通过ORM实现数据的增删改查

引入模块

  • views.py中如果需要使用models.py中的类,需要先引入模块
<project_name>/<app_name>/views.py
1
from .models import User

执行任何SQL语句

<sql>:SQL语句

1
user = User.objects.raw("<sql>")

新增数据

一对一

方式一:直接用内置的方法
  • 直接用内置的objects.create()方法实现数据的新增
1
User.objects.create(字段名=字段值)
方式二:使用save()方法
  • 根据构造方法创建对象,然后调用save()方法保存到数据库
1
2
user = User(字段名=字段值)
user.save()
方式三:使用save()方法
  • 先根据无参构造方法创建对象,然后为属性赋值,最后调用save()方法保存到数据库
1
2
3
user = User()
user.字段名 = 字段值
user.save()

一对多关系

1
2
3
user = User()
oneToMany = OneToMany()
oneToMany.user = user

多对多关系

1
2
3
user = User()
manyToMany = ManyToMany()
manyToMany.user.add(user)

查询数据

一对一

查询所有数据
1
users = User.objects.all()
根据条件查询单条数据
1
user = User.objects.get(字段名=字段值)
根据条件查询多条数据
1
user = User.objects.filter(字段名=字段值)
过滤查询
  • 可以处理User.objects.all()得到的结果或User.objects.filter()得到的结果
  • 将查询的结果进行排除

字段名__exact='':精准匹配字符串
字段名__iexact='':精准匹配字符串,不区分大小写
字段名__contains='':模糊匹配字符串,类似于SQL中的LIKE子句LIKE %字符串%
字段名__icontains='':模糊匹配字符串,不区分大小写,类似于SQL中的LIKE子句LIKE %字符串%
字段名__gt=<num>:大于
字段名__lt=<num>:小于
字段名__gte=<num>:大于等于
字段名__lte=<num>:小于等于
字段名__isnull=True:是否为空
字段名__startswitch='':以什么字符串开头
字段名__istartswitch='':以什么字符串开头,不区分大小写
字段名__endswitch='':以什么字符串结尾
字段名__iendswitch='':以什么字符串结尾,不区分大小写
字段名__in=['', '']:查询结果至少要包含列表中的数据

1
user.exclude(字段名__gt=0)
判断是否查询成功
  • 如果成功查询出对象,则返回True
  • 如果没有成功查询出对象,则返回False
  • 可以处理User.objects.all()得到的结果或User.objects.filter()得到的结果
1
user.exists()
获取查询的结果数量
  • 可以处理User.objects.all()得到的结果或User.objects.filter()得到的结果
1
user.count()
根据指定字段去重
  • 在查询时,指定列每种结果只保留一条数据
  • 只能处理User.objects.filter()得到的结果
1
user.distinct("字段名")
根据指定字段排序
  • 只能处理User.objects.filter()得到的结果
1
user.order_by("字段名")
查询或创建
  • 如果查询成功,则返回数据
  • 如果查询失败,则新增数据到数据库,然后返回数据
1
user = User.objects.get_or_create(字段名=字段值)

一对多

1
user_oneToMany = user.oneToMany

多对多

1
2
user_manyToMany = user.manyToMany
字段值 = user_manyToMany.values("字段名")

聚合查询

  • 每个聚合函数都需要引入额外的模块
求和
1
2
3
from django.db.models import SUM

result = User.objects.all().aggregate(SUM("字段名"))
求平均值
1
2
3
from django.db.models import SVG

result = User.objects.all().aggregate(SVG("字段名"))
计数
1
2
3
from django.db.models import COUNT

result = User.objects.all().aggregate(COUNT("字段名"))
求最大值
1
2
3
from django.db.models import MAX

result = User.objects.all().aggregate(MAX("字段名"))
求最小值
1
2
3
from django.db.models import MIN

result = User.objects.all().aggregate(MIN("字段名"))

修改数据

1
user = User.objects.filter(旧的字段名=旧的字段值).update(新的字段名=新的字段值)

删除数据

1
2
user = User.objects.get(字段名=字段值)
user.delete()

完成

参考文献

哔哩哔哩——图灵学院教程