Skip to content

Django数据模型

更新: 2025/2/24 字数: 0 字 时长: 0 分钟

数据模型,顾名思义肯定是需要和数据库进行一个交互操作。Python有一个三方库pymysql可以连接数据库,并通过sql语句对其操作。然而,Django提供了一种更加方便的操作数据库的流程,就是ORM框架。简单讲,ORM会将程序操作翻译成SQL语句,交给数据库执行。

准备工作

首先,我们需要明白ORM框架不能直接连接数据库,它同样需要借助第三方库来连接,常用的有 pymysqlMySQLdbmysqlclient 等。

安装库

这里我们选择使用对ORM框架支持比较好的 mysqlclient 进行安装。

pip install mysqlclient

创建数据库

**ORM框架不能帮助我们创建数据库,只能自己创建。**这里我们创建一个和项目同名的 mysite 数据库,SQL语句如下:

CREATE DATABASE mysite DEFAULT CHARSET utf8 COLLATE utf8_grneral_ci;

QQ截图20220514181719

配置数据库

创建好了数据库,接下来就是连接我们的数据库了。打开项目的 settings.py 文件,可以看到当中一段 DATABASES 配置,默认使用了sqlite3数据库,就是项目中的 db.splite3 文件:

QQ截图20220514182134

现在我们可以删除掉 db.splite3 文件,将 DATABASES 修改为如下配置:

python
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',  # 连接数据库类型
        'NAME': 'mysite',  # 数据库名称
        'USER': 'root',  # 登录用户
        'PASSWORD': '123456',  # 用户密码
        'HOST': '127.0.0.1',  # MySQL所在主机IP
        'PORT': 3306  # 端口
    }
}

QQ截图20220514183016

ORM操作

通过配置我们连接上了数据库,现在就可以通过ORM框架来操作数据库了。

表操作

创建表

**在ORM中创建表的操作是依托于Python中的类来进行创建。**打开app01应用中的 models.py 文件,添加如下代码:

python
from django.db import models

# 创建一个UserInfo类,固定继承models.Model类
class UserInfo(models.Model):
    # Django会自动的生成id字段,并设置为主键,当然你也可以自己写    
    # AutoField自增int类型,
    # BigAutoField自增bigint类型
    # SmallAutoField自增tinyint类型
    # primary_key为主键
    # id = models.AutoField(primary_key=True)
    # CharField字符类型,max_length最大长度
    name = models.CharField(max_length=32)
    password = models.CharField(max_length=64)
    # IntegerField数值类整型
    age = models.IntegerField()

QQ截图20220514184820

当Django中ORM框架读到这个类就会将转译成如下SQL语句:

sql
/*
表名组成:应用名称_小写的类名
字段组成:除了类中定义的字段,还会自动添加id字段,并设置为主键
*/
create table app01_userinfo(
    id bigint auto_increment primary key,
    name varchar(32),
    password varchar(64),
    age int
)

接下来,我们在命令行的项目路径下的项目环境中执行如下命令:

python manage.py makemigrations

该命令会读取注册的app01应用下 models.py 文件内容中类,在app01应用下的 migrations 文件夹下,生成对应的数据库表模型 0001_initial.py 文件:

QQ截图20220514190735

接下来,我们继续执行如下命令:

python manage.py migrate

执行后我们会在数据库看到如下表,其中第一个就是我们通过UserInfo类创建的 app01_userinfo 表:

QQ截图20220514193211

查看 app01_userinfo 表结构,也和我们类中定义的字段、属性一样:

QQ截图20220514193552

这里额外解释一下,除了创建 app01_userinfo 表,还创建了很多其他的表,这是因为创建表时,会读取已注册的app,Django默认添加了许多其他的app,这些都是内置提供的功能,而这些功能依赖于数据表,所以会生成这些默认表。

QQ截图20220514193845

新增表

如果后期需要新增数据表或者去除某字段只需要在 models.py 中添加好对应的类或者注释掉相应的字段,再执行这两条命令即可:

python manage.py makemigrations
python manage.py migrate

减字段

如果后期需要新增数据表或者去除某字段只需要在 models.py 中添加好对应的类或者注释掉相应的字段,再执行这两条命令即可:

python manage.py makemigrations
python manage.py migrate

加字段

**但在 models.py 文件对应类中新增字段就必须加上一个默认值。这是因为表中其他字段可能已有数据,必须给新增字段一个默认值。**例如,我们在UserInfo类新增 size 字段、data 字段代码如下:

python
from django.db import models

# 创建一个UserInfo类,固定继承models.Model类
class UserInfo(models.Model):
    # CharField字符类型,max_length最大长度
    name = models.CharField(max_length=32)
    password = models.CharField(max_length=64)
    # IntegerField数值类整型
    age = models.IntegerField()
    # 新增字段,default默认值为1
    size = models.IntegerField(default=1)
    # 新增字段,默认为空
    data = models.IntegerField(null=True, blank=True)

再执行这两条命令:

python manage.py makemigrations
python manage.py migrate

再去数据表中查看结构,就能看到新增的 size 字段、data 字段:

QQ截图20220514201130

数据操作

添加数据

上面我们成功在数据库中添加了 app01_userinfo 表,现在我们通过视图函数向里面添加数据。在 urls.py 文件中新增如下代码,注册一个 add_data 视图函数:

python
path('add/data/', app01.views.add_data)

QQ截图20220515014423

views.py 文件中,添加如下代码:

python
# 从模型中引入UserInfo类
from app01.models import UserInfo

def add_data(request):
    # UserInfo.objects.create创建UserInfo类对象添加进数据表中
    UserInfo.objects.create(name="李白", password="123", age="18", size="9", data="9")
    UserInfo.objects.create(name="杜甫", password="345", age="19", size="8")
    UserInfo.objects.create(name="李清", password="567", age="20")
    return HttpResponse('数据添加成功!')

QQ截图20220515020826

现在我们访问该视图对应的地址 http://127.0.0.1:8000/add/data/ 页面如下:

QQ截图20220515015528

我们在去 mysite 数据库中查看 app01_userinfo 表中的数据,结果如下:可以看到,杜甫一行的 data 为空,这是因为创建杜甫对象时未给 data 字段赋值,而在模型中UserInfo类定义 data 字段默认值为空。在李清一行的 size 为1,这是因为创建李清对象时未给 size 字段赋值,而在模型中UserInfo类定义 size 字段默认值为1。

QQ截图20220515015659

删除数据

删除数据和添加数据类似,首先在 urls.py 文件中新增如下代码,注册一个 del_data 视图函数:

python
path('del/data/', app01.views.del_data)

QQ截图20220515021007

views.py 文件中,添加如下代码:

python
def del_data(request):
    # 删除id为3的数据
    UserInfo.objects.filter(id=3).delete()
    # 删除整张表的所有数据(表还存在)
    # UserInfo.objects.all().delete()
    return HttpResponse('数据删除成功!')

QQ截图20220515022016

现在我们访问该视图对应的地址 http://127.0.0.1:8000/del/data/ 页面如下:

QQ截图20220515022125

我们在去 mysite 数据库中查看 app01_userinfo 表中的数据,结果如下:可以看到id为3的数据已经被删除了。

QQ截图20220515022249

获取数据

首先在 urls.py 文件中新增如下代码,注册一个 get_data 视图函数:

python
path('get/data/', app01.views.get_data)

QQ截图20220515022819

views.py 文件中,添加如下代码:

python
def get_data(request):
    # 返回结果是列表里面包含一个id为2的对象
    row = UserInfo.objects.filter(id=2)[0]
    print(row.id, row.name, row.password, row.age, row.size, row.data)
    print('*' * 50)
    # 返回结果是列表里面包含全部的id的对象
    all = UserInfo.objects.all()
    for row in all:
        print(row.id, row.name, row.password, row.age, row.size, row.data)
    return HttpResponse('数据获取成功!')

QQ截图20220515024147

现在我们访问该视图对应的地址 http://127.0.0.1:8000/get/data/ 页面如下:

QQ截图20220515024222

控制台输出了如下信息:

QQ截图20220515024324

更新数据

首先在 urls.py 文件中新增如下代码,注册一个 up_data 视图函数:

python
path('up/data/', app01.views.up_data)

QQ截图20220515024628

views.py 文件中,添加如下代码:

python
def up_data(request):
    # 更新李白的size字段值为7
    UserInfo.objects.filter(name="李白").update(size=7)
    # 更新整张表的age字段值为999
    UserInfo.objects.all().update(age=999)
    return HttpResponse('数据更新成功!')

QQ截图20220515024953

现在我们访问该视图对应的地址 http://127.0.0.1:8000/up/data/ 页面如下:

QQ截图20220515025105

我们在去 mysite 数据库中查看 app01_userinfo 表中的数据,结果如下:李白的size已经改为7,所有数据的age字段值都设置为999。

QQ截图20220515025238