0%

Django(三) 模型:ORM框架、定义模型类并创建一个对应的数据库、配置Mysql数据库

详情请点阅读全文

一、模型概述

https://docs.djangoproject.com/zh-hans/3.0/intro/tutorial02/
https://www.runoob.com/django/django-model.html
Django 对各种数据库提供了很好的支持,包括:PostgreSQL、MySQL、SQLite、Oracle。

Django 为这些数据库提供了统一的调用API。 我们可以根据自己业务需求选择不同的数据库。

MySQL 是 Web 应用中最常用的数据库。本章节我们将以 Mysql 作为实例进行介绍。你可以通过本站的 MySQL 教程 了解更多Mysql的基础知识。

二、ORM框架简介

在这里插入图片描述

  • django中内嵌了ORM框架,ORM框架可以将类和数据表进行对应起来,只需要通过类和对象就可以对数据表进行操作。
  • 在Django中主要是设计类:模型类。
  • ORM另外一个作用:根据设计的类生成数据库中的表。

Django的ORM框架

在这里插入图片描述

  • O(objects):类和对象。
  • R(Relation):关系,关系数据库中的表格。
  • M(Mapping):映射。

Django ORM框架的功能:

  • a)建立模型类和表之间的对应关系,允许我们通过面向对象的方式来操作数据库。
  • b)根据设计的模型类生成数据库中的表格。
  • c)通过方便的配置就可以进行数据库的切换。

    三、定义模型类以实现数据库表的建立

    https://blog.csdn.net/u010132177/article/details/103788677 创建的项目
    目录结构如下:不重要部分已删除
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    D:\a\django-app\project1>tree /f
    │ db.sqlite3
    │ manage.py
    ├─app1
    │ │ admin.py
    │ │ apps.py
    │ │ models.py
    │ │ tests.py
    │ │ views.py
    │ │ __init__.py
    │ │
    │ ├─migrations
    │ │ │ __init__.py
    └─project1
    │ asgi.py
    │ settings.py
    │ urls.py
    │ wsgi.py
    │ __init__.py

3.1定义模型类,并在数据库生成对应的表

第1步,在models.py定义类(\pj1\app-te1\models.py)

1
2
3
4
5
6
7
8
9
10
11
12
from django.db import models
# 设计和表对应的类,模型类
# Create your models here.

# 一类
# 图书类
class BookInfo(models.Model):
'''图书模型类'''
# 图书名称,CharField说明是一个字符串,max_length指定字符串的最大长度
btitle = models.CharField(max_length=20)
# 出版日期,DateField说明是一个日期类型
bpub_date = models.DateField()

第2步,生成迁移文件

命令:python manage.py makemigrations

  • 迁移文件是根据模型类生成的。
  • 会在生成一个迁移文件:app1\migrations\0001_initial.py
    1
    2
    3
    4
    > py manage.py makemigrations
    # Migrations for 'app1':
    # app1\migrations\0001_initial.py
    # - Create model BookInfo

0001_initial.py 详情:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from django.db import migrations, models

class Migration(migrations.Migration):
initial = True
dependencies = [
]

operations = [
migrations.CreateModel(
name='BookInfo',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('btitle', models.CharField(max_length=20)),
('bpub_date', models.DateField()),
],
),
]

第3步,执行迁移文件,在数据库生成表

命令:python manage.py migrate

  • 根据迁移文件,在数据库生成表。(默认是sqlite数据库)
  • 生成表名的默认格式:应用名_模型类名小写

执行详情:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
D:\a\django-app\project1>py manage.py migrate

Operations to perform:
Apply all migrations: admin, app1, auth, contenttypes, sessions
Running migrations:
Applying contenttypes.0001_initial... OK
Applying auth.0001_initial... OK
Applying admin.0001_initial... OK
Applying admin.0002_logentry_remove_auto_add... OK
Applying admin.0003_logentry_add_action_flag_choices... OK
Applying app1.0001_initial... OK
Applying contenttypes.0002_remove_content_type_name... OK
Applying auth.0002_alter_permission_name_max_length... OK
Applying auth.0003_alter_user_email_max_length... OK
Applying auth.0004_alter_user_username_opts... OK
Applying auth.0005_alter_user_last_login_null... OK
Applying auth.0006_require_contenttypes_0002... OK
Applying auth.0007_alter_validators_add_error_messages... OK
Applying auth.0008_alter_user_username_max_length... OK
Applying auth.0009_alter_user_last_name_max_length... OK
Applying auth.0010_alter_group_name_max_length... OK
Applying auth.0011_update_proxy_permissions... OK
Applying sessions.0001_initial... OK

注:生成的表放在数据库 【db.sqlite3】 内,表详情如下(booktest_bookinfo应为app1_bookinfo)
在这里插入图片描述

第4步,通过模型类操作数据表:

进入项目shell的命令:
python manage.py shell
以下为在相互shell终端中演示的例子:

0)首先导入模型类:

1
from booktest.models import BookInfo,HeroInfo

1)向booktest_bookinfo表中插入一条数据。

1
2
3
4
b = BookInfo() #定义一个BookInfo类的对象
b.btitle ='天龙八部' #定义b对象的属性并赋值
b.bpub_date = date(1990,10,11)
b.save() #才会将数据保存进数据库

2) 查询出booktest_bookinfo表中id为1的数据。

1
b = BookInfo.objects.get(id=1)

3) 在上一步的基础上改变b对应图书的出版日期。

1
2
b.bpub_date = date(1989,10,21)
b.save() #才会更新表格中的数据

4) 紧接上一步,删除b对应的图书的数据。

1
b.delete() #才会删除

5) 向booktest_heroInfo表中插入一条数据。

1
2
3
4
5
6
7
h = HeroInfo()
h.hname = '郭靖'
h.hgender = False
h.hcomment = ‘降龙十八掌’
b2 = BookInfo.objects.get(id=2)
h.hbook = b2 #给关系属性赋值,英雄对象所属的图书对象
h.save()

6) 查询图书表里面的所有内容。

1
2
BookInfo.objects.all()
HeroInfo.objects.all()

第4步实操记录,增、删、改、查

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
D:\a\django-app\project1>py manage.py shell
Python 3.7.1 (v3.7.1:260ec2c36a, Oct 20 2018, 14:57:15) [MSC v.1915 64 bit (AMD6
4)] on win32
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from app1.models import BookInfo
>>> b=BookInfo()
>>> b.btitle='天龙八部'
>>> from datetime import date
>>> b.bpub_date=date(1998,1,2)
>>> b.save()
>
#【★★★查寻所有数据】
>>> BookInfo.objects.all()
<QuerySet [<BookInfo: BookInfo object (1)>]>

#【★★★查询单条数据】获取id=1的BookInfo信息
>>> b2=BookInfo.objects.get(id=1)
>>> type(b2)
<class 'app1.models.BookInfo'>
>>> b2
<BookInfo: BookInfo object (1)>

#【查看对应数据】
>>> b2.btitle
'天龙八部'
>>> b2.bpub_date
datetime.date(1998, 1, 2)
>>> b2.id
1

#【更新对应数据】,要保存之后才会生效
>>> b2.bpub_date=date(1991,2,2)
>>> b2.save()
b2.delete() #也可删除对应数据
b.delete()# 删除刚刚插入的数据

第5步,再加一个models.py类,且加上关联

再加一个models.py类,定义一个新数据表,且与BookInfo类表建立关联

1
2
3
4
5
6
7
8
9
10
11
错误解决: https://blog.csdn.net/weixin_33991727/article/details/93075685

报错:
TypeError: init() missing 1 required positional argument: 'on_delete'

原因:
在django2.0后,定义外键和一对一关系的时候需要加on_delete选项,
此参数为了避免两个表里的数据不一致问题,不然会报错:

解决:把最后一句关联选项加一个on_delete参数。
hbook = models.ForeignKey('BookInfo', on_delete=models.CASCADE)

1)在project1/models.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
from django.db import models
# 设计和表对应的类,模型类
# Create your models here.

# 一类
# 图书类
class BookInfo(models.Model):
'''图书模型类'''
# 图书名称,CharField说明是一个字符串,max_length指定字符串的最大长度
btitle = models.CharField(max_length=20)
# 出版日期,DateField说明是一个日期类型
bpub_date = models.DateField()

# 多类
# 英雄人物类
# 英雄名 hname
# 性别 hgender
# 年龄 hage
# 备注 hcomment
# 关系属性 hbook,建立图书类和英雄人物类之间的一对多关系
class HeroInfo(models.Model):
'''英雄人物模型类'''
hname = models.CharField(max_length=20) # 英雄名称
# 性别,BooleanField说明是bool类型,default指定默认值,False代表男
hgender = models.BooleanField(default=False)
# 备注
hcomment = models.CharField(max_length=128)
# 关系属性 hbook,建立图书类和英雄人物类之间的一对多关系
# 关系属性对应的表的字段名格式: 关系属性名_id
hbook = models.ForeignKey('BookInfo', on_delete=models.CASCADE) #对应BookInfo表的主键ID

1.1建立迁移文件,并利用其创建对应的 HeroInfo表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
\project1>py manage.py makemigrations
'''
Migrations for app1:
app1\migrations\0002_heroinfo.py
- Create model HeroInfo
'''

\project1>py manage.py migrate
'''
Operations to perform:
Apply all migrations: admin, app1, auth, contenttypes, sessions
Running migrations:
Applying app1.0002_heroinfo... OK
'''

2)向HeroInfo插入数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
D:\a\django-app\project1>py manage.py shell
Python 3.7.1 (v3.7.1:260ec2c36a, Oct 20 2018, 14:57:15) [MSC v.1915 64 bit (AMD6
4)] on win32
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from app1.models import BookInfo,HeroInfo
>>> from datetime import date
>>> b=BookInfo()
>>> b.title='天龙八部'
>>> b.bpub_date=date(1992,1,1)
>>> b.save()
>
>>> h=HeroInfo()
>>> h.hname='段誉'
>>> h.hgender=False #性别男
>>> h.comment='六脉神剑'
>>> h.hbook=b #关联键,要关联BookInfo,必须要关联到 对应表的对象,b=BookInfo()
>>> h.save()

>>> h2=HeroInfo()
>>> h2.hname='乔峰'
>>> h2.hgender=False #性别男
>>> h2.comment='降龙十八掌'
>>> h2.hbook=b #关联键,要关联BookInfo,必须要关联到 对应表的对象,b=BookInfo()
>>> h2.save()

在这里插入图片描述

6.关联操作

1) 查询出id为2的图书中所有英雄人物的信息。
在这里插入图片描述

1
2
b = BookInfo.objects.get(id=2)
b.heroinfo_set.all() #查询出b图书中所有英雄人物的信息

知识点:如果加入了中文要在py文件头部加如下一行:

1
# -*- coding: UTF-8 -*-

四、Django的mysql数据库配置

【参考】:https://docs.djangoproject.com/zh-hans/3.0/ref/databases/#mysql-notes
https://www.w3cschool.cn/mysql/mysql-install.html
https://blog.csdn.net/zx_water/article/details/79015603
【可视管理数据库】最好用的支持各个:navicat premium

4.1安装mysql

安装完成后需要配置环境变量(注意是mysql server 8.0):

1
C:\Program Files\MySQL\MySQL Server 8.0\bin

4.2 启动Mysql服务

cmd中

1
2
3
4
5
启动服务:
net start mysql

结束服务:
net stop mysql

如果不能启动,则计算机(右键)——管理——服务,找mysql

在这里插入图片描述
可发现此处mysql名变成了mysql80因此正确命令应是:

1
2
3
4
5
启动服务:
net start mysql80

结束服务:
net stop mysql80

4.3 通过cmd连接mysql命令:

mysql命令cmd详情

1
2
3
4
5
6
7
8
9
10
11
12
13
14
登录mysql数据库:
mysql –uroot –p #之后输入密码p.2

查看有哪些数据库:
show databases; #此处必须有分号,否则不会显示数据库

创建数据库:
create database test2 charset=utf8; #切记:指定编码

使用数据库:
use test2;

查看数据库中的表:
show tables;

cmd连接mysql实战

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
C:\Users\Administrator>mysql -uroot -p
Enter password: ******
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 16
Server version: 8.0.13 MySQL Community Server - GPL

Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sakila |
| spiders |
| sys |
| world |
+--------------------+
7 rows in set (0.00 sec)

mysql> create database test888 charset=utf8;
Query OK, 1 row affected, 1 warning (0.21 sec)

mysql> use test888
Database changed
mysql> use test888;
Database changed
mysql> show tables;
Empty set (0.00 sec)

mysql>

4.4 Django配置使用mysql数据库

  • 在此之前必须配置,安装好Mysql数据库,并新建一个数据库。(test888)

修改project1/settings.py中的DATABASES:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# Database
# https://docs.djangoproject.com/en/3.0/ref/settings/#databases
DATABASES = {
'default': {
# 'ENGINE': 'django.db.backends.sqlite3',
# 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),

'ENGINE': 'django.db.backends.mysql',#mysql连接
'NAME': 'test888', # 使用的数据库的名字,数据库必须手动创建
'USER': 'root', # 链接mysql的用户名
'PASSWORD': 'p.2', # 用户对应的密码
'HOST': 'localhost', # 指定mysql数据库所在电脑ip
'PORT': 3306, # mysql服务的端口号
}
}

4.5 退出cmd的server服务重启报错:

1
2
3
4
5
6
7
8
9
D:\a\django-app\project1>py manage.py runserver
Watching for file changes with StatReloader
Exception in thread django-main-thread:
Traceback (most recent call last):
.
.
.
django.core.exceptions.ImproperlyConfigured: Error loading MySQLdb module.
Did you install mysqlclient?

4.6安装驱动

如果你没安装 mysql 驱动,会有4.5步的报错,可以执行以下命令安装:

1
2
3
4
5
#windows:
pip install mysqlclient

# linux
sudo pip install mysqlclient

4.6重新创建移动model文件,并执行

1
2
3
4
5
#生成迁移文件,如果模型没变直接运行执行即可
py manage.py makemigrations

#执行迁移文件生成对应的表
py manage.py migrate

实战:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
D:\a\django-app\project1>py manage.py makemigrations
No changes detected

D:\a\django-app\project1>py manage.py migrate
Operations to perform:
Apply all migrations: admin, app1, auth, contenttypes, sessions
Running migrations:
Applying contenttypes.0001_initial... OK
Applying auth.0001_initial... OK
Applying admin.0001_initial... OK
Applying admin.0002_logentry_remove_auto_add... OK
Applying admin.0003_logentry_add_action_flag_choices... OK
Applying app1.0001_initial... OK
Applying app1.0002_heroinfo... OK
Applying contenttypes.0002_remove_content_type_name... OK
Applying auth.0002_alter_permission_name_max_length... OK
Applying auth.0003_alter_user_email_max_length... OK
Applying auth.0004_alter_user_username_opts... OK
Applying auth.0005_alter_user_last_login_null... OK
Applying auth.0006_require_contenttypes_0002... OK
Applying auth.0007_alter_validators_add_error_messages... OK
Applying auth.0008_alter_user_username_max_length... OK
Applying auth.0009_alter_user_last_name_max_length... OK
Applying auth.0010_alter_group_name_max_length... OK
Applying auth.0011_update_proxy_permissions... OK
Applying sessions.0001_initial... OK

4.7 安装完成后,启动web服务即可:

1
py manage.py runserver

4.8效果 http://127.0.0.1:8000

4.9 完成

4.10 第4部分接:Django(五)