发布于 

django学习笔记(2):操作MySQL数据库

使用 django 操作 mysql 数据库。

前言

  数据库是 web 应用中很重要的组成部分之一。Django 框架自带了 sqlite3 数据库,然而在使用的广泛程度上,MySQL 的应用场景更加多。本篇主要解释如何将数据库换成 MySQL,以及一些基本用法。

更换默认数据库为 MySQL

创建数据库

  由于 django 的 orm 只能完成对于表的操作,因此数据库的创建需要我们自行完成,这里以本地 MySQL 数据库为例。在 MySQL 终端输入

完成数据库的创建。然后运行 use {db_name} ,若提示为 empty set(空的数据库),则创建成功。

安装第三方依赖

  首先我们需要安装第三方包 pymysql (你也可以使用mysqlclient),这个第三方包能够帮助 Django 完成对 MySQL 数据库的增删改查操作,

如果安装缓慢,可以参考本系列的第一篇文章,将安装源换成国内镜像站。

更改项目配置文件

  在项目目录下找到setting.py,找到DATABASES,这里默认是

1
2
3
4
5
6
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}

其中, ENGINE 指明了数据库类型, NAME 指明了数据库名称。默认情况下,Django 使用内部集成的 sqlite3.我们修改之,

1
2
3
4
5
6
7
8
9
10
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'webapp', # 数据库名字
'USER': 'root',
'PASSWORD': '{你的密码}',
'HOST': '127.0.0.1', # MySQL 在哪个 ip
'PORT': '3306', # 端口号
}
}

其中,HOST是主机 ip,这里使用的是本地,因此是127.0.0.1PORT是端口号,本地 MySQL 的端口号是3306。然后,你需要在项目的_init_.py中添加:

1
2
3
import pymysql

pymysql.install_as_MySQLdb()

使用 Django 操作 MySQL 的表

创建表

  表的操作都可以用 python 语法完成,其中 orm 会将其翻译成 SQL 语句,对于我们来说,无需自己再写 SQL 语句了。

  在已注册的应用下的models.py中新建类,例如我们要创建一个用户信息的表,那么我们可以写成

1
2
3
4
5
6
from django.db import models

class UserInfo(models.Model):
name = models.CharField(max_length=32)
password = models.CharField(max_length=64)
age = models.IntegerField(default=0)

然后,我们在终端运行

这时,Django 自动为我们创建了表,其相当于

1
2
3
4
5
6
create table app01_userinfo(
id bigint auto_increment primary key,
name varchar(32),
password varchar(64),
age int
)

在 MySQL 终端输入

终端输出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
mysql> show tables;
+----------------------------+
| Tables_in_webapp |
+----------------------------+
| app01_userinfo |
| auth_group |
| auth_group_permissions |
| auth_permission |
| auth_user |
| auth_user_groups |
| auth_user_user_permissions |
| django_admin_log |
| django_content_type |
| django_migrations |
| django_session |
+----------------------------+
11 rows in set (0.00 sec)

这表明,app01_userinfo的表已经被创建。当然,这里其他的表示 Django 内部的其他类,我们这里无需在意。接下来我们检查字段。MySQL 终端输入

观察到输出

1
2
3
4
5
6
7
8
9
10
mysql> desc app01_userinfo;
+----------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+----------------+
| id | bigint | NO | PRI | NULL | auto_increment |
| name | varchar(32) | NO | | NULL | |
| password | varchar(64) | NO | | NULL | |
| age | int | NO | | NULL | |
+----------+-------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)

其中,namepasswordage都是我们所定义的字段,id是 Django 自动创建的字段。

修改表

  当然,我们也免不了修改表的字段数,例如,我们不需要age这一个字段了,我们只需要在models.py下删除之。

1
2
3
4
5
6
7
8
from django.db import models

class UserInfo(models.Model):
name = models.CharField(max_length=32)
password = models.CharField(max_length=64)

- age = models.IntegerField(default=0)

然后重新在终端执行makemigrationsmigrate二连,我们就可以观察到这一字段消失了。

  有时候,我们也会为表中新增字段,例如:

1
2
3
4
5
6
7
8
9
from django.db import models

class UserInfo(models.Model):
name = models.CharField(max_length=32)
password = models.CharField(max_length=64)
age = models.IntegerField(default=0)

- sex = models.CharField(max_length=4)

执行数据迁移二连,我们会发现控制台有警报。

这是因为,当我们添加字段时,如果表中有数据,那么这些数据的新字段的值我们就不得而知。因此,会产生上述的告警。控制台给了我们两种解决方式:

  1. 为已有的数据分配初始值来填补这些空缺;
  2. models.py中声明初始值。

对于选择 1,我们可以将已有的数据的该字段的值赋值成为我们指定的值,这里不多说了。对于选择 2,则需要为该字段指定默认值,那么上述语句可以被重写成

1
2
3
4
5
6
7
8
9
class UserInfo(models.Model):
name = models.CharField(max_length=32)
password = models.CharField(max_length=64)
age = models.IntegerField(default=0)

- sex = models.CharField(max_length=4)

* sex = models.CharField(max_length=4, default='male')

于是,控制台告警消失,并且之前所有已存在的数据的新字段都被赋值为初始值。当然了,你也可以声明该字段允许为空,例如:

1
2
3
4
5
6
7
8
9
class UserInfo(models.Model):
name = models.CharField(max_length=32)
password = models.CharField(max_length=64)
age = models.IntegerField(default=0)

- sex = models.CharField(max_length=4, default='male')

* sex = models.CharField(max_length=4,blank=True,null=True)

这样也是可以的。

使用 Django 操作 MySQL 中的数据

  我们依然可以用 python 语句来操作 MySQL 中的数据。

创建数据

  创建数据的语法是:

1
{类名}.objects.create(参数列表)

例如我们需要在app01_userinfo中插入一段记录,以下就是一个例子:

1
UserInfo.objects.create(name="Felix", password="123", age=19)

这句 python 会被 orm 翻译成 SQL 语句:

1
insert into app01_userinfo(name, password, age)value("Felix", "123", 19)

删除数据

  删除数据的语法是:

1
{类名}.objects.filter(筛选条件).delete()

如果你要清空数据,那么可以写成

1
{类名}.objects.all().delete()

当然,过滤函数还有许多写法,这里只展示了filter()all()

查找数据

  查找数据的语法是

1
{类名}.objects.filter(筛选条件)

函数的返回值是一个QuerySet类型,在 python 中,其可以被理解成结构体对象的列表,例如

[<UserInfo: UserInfo object (1)>, <UserInfo: UserInfo object (2)>, <UserInfo: UserInfo object (3)>]

如果我们要读取其内部值,就可以用简单的 python 语法实现,这里举个例子:

1
2
3
user_info_list = UserInfo.objects.all()
for obj in user_info_list:
print(obj.id, obj.name, obj.password, obj.age)

当然,如果我们明确知道表中只有一行数据,那么我们可以避免使用循环,直接用

1
obj = UserInfo.objects.all().first()

获取对象即可。

更新数据

  更新数据,首先要找到需要更新的记录,因此,前一部分与查找是很相似的。update()函数完成后续的更新操作,例如:

1
UserInfo.objects.filter(id=2).update(password = "999")

则被筛选出的记录的password字段都会被更新成999

后记

  有了与数据库的联动操作,我们已经可以写一些基础的业务逻辑了。当然,Django 对于数据库的操作远不止这些。