[实验] Django 逻辑条件数据查询

注意:

本实验是接着 《Django 最大值、最小值、平均值等特殊数值的数据查询》而继续的

正文:

步骤一:进入相应的 Django 环境

(django_env) [root@python mysite]# python3
>>> import os,django
>>> os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings")
'mysite.settings'
>>> django.setup()
>>> from user.models import *

步骤二:导入逻辑条件查询 Q 模块

>>> from django.db.models import Q

步骤三:设置 1 个显示上 1 句 SQL 语句的函数

>>> def showsql():
...     from django.db import connection
...     print(connection.queries[-1]['sql'])
... 

步骤四:进行逻辑条件查询

4.1 Django 进行与查询

4.1.1 通过 Q 查询进行与查询
4.1.1.1 通过 Q 查询进行与查询
>>> Student.objects.filter(Q(sname='lisi')&Q(score=80))
<QuerySet [<Student: Student:lisi,80>]>


补充:
1) 这里以查询同时满足 sname=’lisi’ 条件和 score=80 条件的数据为例
2) 这里共查询到了 1 条数据

4.1.1.2 显示通过 Q 查询进行与查询的 SQL 语句
>>> showsql()
SELECT `user_student`.`id`, `user_student`.`sname`, `user_student`.`score`, `user_student`.`cls_id` FROM `user_student` WHERE (`user_student`.`sname` = 'lisi' AND `user_student`.`score` = 80) LIMIT 21

(补充:这里以查询同时满足 sname=’lisi’ 条件和 score=80 条件的数据为例)

4.1.2 通过 filter 进行与查询
4.1.2.1 通过 filter 进行与查询
>>> Student.objects.filter(sname='lisi',score=80)
<QuerySet [<Student: Student:lisi,80>]>


补充:
1) 这里以查询同时满足 sname=’lisi’ 条件和 score=80 条件的数据为例
2) 这里共查询到了 1 条数据

4.1.2.2 显示通过 filter 进行与查询的 SQL 语句
>>> showsql()
SELECT `user_student`.`id`, `user_student`.`sname`, `user_student`.`score`, `user_student`.`cls_id` FROM `user_student` WHERE (`user_student`.`score` = 80 AND `user_student`.`sname` = 'lisi') LIMIT 21

(补充:这里以查询同时满足 sname=’lisi’ 条件和 score=80 条件的数据为例)

4.2 Django 进行或查询

4.2.1 通过 Q 查询进行或查询
>>> Student.objects.filter(Q(sname='zhangsan')|Q(score=90))
<QuerySet [<Student: Student:zhangsan,60>, <Student: Student:wangwu,90>]>


补充:
1) 这里以查询同时满足 sname=’lisi’ 条件或 score=90 条件的数据为例
2) 这里共查询到了 1 条数据

4.2.2 显示通过 Q 查询进行或查询的 SQL 语句
>>> showsql()
SELECT `user_student`.`id`, `user_student`.`sname`, `user_student`.`score`, `user_student`.`cls_id` FROM `user_student` WHERE (`user_student`.`sname` = 'zhangsan' OR `user_student`.`score` = 90) LIMIT 21

(补充:这里以查询同时满足 sname=’lisi’ 条件或 score=90 条件的数据为例)

4.3 Django 进行非查询

4.3.1 通过 Q 查询进行非查询
>>> Student.objects.filter(~Q(sname='zhangsan'))
<QuerySet [<Student: Student:lisi,80>, <Student: Student:wangwu,90>, <Student: Student:zhaoliu,70>, <Student: Student:xueer,70>, <Student: Student:huangyi,70>]>


补充:
1) 这里以查询 sname=’zhangsan’ 条件不成立的数据为例
2) 这里共查询到了 5 条数据

4.3.2 显示通过 Q 查询进行非查询的 SQL 语句
>>> showsql()
SELECT `user_student`.`id`, `user_student`.`sname`, `user_student`.`score`, `user_student`.`cls_id` FROM `user_student` WHERE NOT (`user_student`.`sname` = 'zhangsan') LIMIT 21

(补充:这里以查询 sname=’zhangsan’ 条件不成立的数据为例)

4.4 Django 进行与非组合查询

4.4.1 通过 Q 查询进行与非组合查询
>>> Student.objects.filter(~Q(sname='zhangsan',score=90))
<QuerySet [<Student: Student:zhangsan,60>, <Student: Student:lisi,80>, <Student: Student:wangwu,90>, <Student: Student:zhaoliu,70>, <Student: Student:xueer,70>, <Student: Student:huangyi,70>]>


补充:
1) 这里以查询同时满足 sname=’lisi’ 条件和 score=80 条件不成立的数据为例
2) 这里共查询到了 1 条数据

4.4.2 显示通过 Q 查询进行与非组合查询的 SQL 语句
>>> showsql()
SELECT `user_student`.`id`, `user_student`.`sname`, `user_student`.`score`, `user_student`.`cls_id` FROM `user_student` WHERE NOT (`user_student`.`score` = 90 AND `user_student`.`sname` = 'zhangsan') LIMIT 21

(补充:这里以查询同时满足 sname=’lisi’ 条件和 score=80 条件不成立的数据为例)

[实验] Django 自定义一个数据查询函数

注意:

本实验是接着 《Django 最大值、最小值、平均值等特殊数值的数据查询》而继续的

正文:

步骤一:进入相应的 Django 环境

(django_env) [root@python mysite]# python3
>>> import os,django
>>> os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings")
'mysite.settings'
>>> django.setup()
>>> from user.models import *

步骤二:自定义 1 个查询对象

>>> def test(sql):
...     from django.db import connection
...     with connection.cursor() as c:
...         c.execute(sql)
...         for info in c.fetchall():
...             print(info)
...

(补充:这里以自定义名为 test 的自定义查询对象为例)

步骤三:使用自定义查询对象查询数据

>>> test('select * from user_clazz')
(1, 'Class1')
(2, 'Class2')


补充:这里以
1) 使用 test 对象
2) 执行 select * from user_clazz SQL 语句
3) 查询结果是 1 Class1,2 Class2 两条数据
为例

[实验] Django 通过 SQL 语句进行数据查询

注意:

本实验是接着 《Django 最大值、最小值、平均值等特殊数值的数据查询》而继续的

正文:

步骤一:进入相应的 Django 环境

(django_env) [root@python mysite]# python3
>>> import os,django
>>> os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings")
'mysite.settings'
>>> django.setup()
>>> from user.models import *

步骤二:Django SQL 语句完全查询

>>> user = Student.objects.raw('select * from user_student')
>>> for s in user:
...     print(s)
... 
Student:zhangsan,60
Student:lisi,80
Student:wangwu,90
Student:zhaoliu,70
Student:xueer,70
Student:huangyi,70

(补充:这里以查看 user_student 表中的所有数据为例)

步骤三:Django SQL 语句部分查询

3.1 导入 Django SQL 语句部分查询的模块

>>> from django.db import connection

3.2 Django SQL 语句部分查询(含主键查询)

3.2.1 创建游标(含主键查询)
>>> cur = connection.cursor()

(补充:这里以创建名为 cur 的游标为例)

3.2.2 查询数据并导入游标(含主键查询)
>>> cur.execute('select * from user_student')
6


补充:
1) 这里以查询 user_student 表里到所有数据并导入 cur 游标为例
2) 这里查出的数据总共有 6 条

3.2.3 将游标里的数据导入到变量里(含主键查询)
>>> cs = cur.fetchall()

(补充:这里以将数据导入到 cs 变量里为例)

3.2.4 将游标里的数据以对象的形式显示出来(含主键查询)
>>> print(cs)
((1, 'zhangsan', 60, 1), (2, 'lisi', 80, 1), (3, 'wangwu', 90, 1), (4, 'zhaoliu', 70, 1), (5, 'xueer', 70, 2), (6, 'huangyi', 70, 2))

(补充:这里显示出来的是对象)

3.2.5 将游标里的数据以列表的形式显示出来(含主键查询)
>>> for c in cs:
...     print(c)
... 
(1, 'zhangsan', 60, 1)
(2, 'lisi', 80, 1)
(3, 'wangwu', 90, 1)
(4, 'zhaoliu', 70, 1)
(5, 'xueer', 70, 2)
(6, 'huangyi', 70, 2)

(补充:这里打出来的是列表)

3.2.6 关闭游标(含主键查询)
>>> cur.close()

(补充:这里以关闭 cur 游标为例)

3.3 Django SQL 语句部分查询(不包含主键)

3.3.1 创建游标(不包含主键)

>>> cur = connection.cursor()

(补充:这里以创建名为 cur 的游标为例)

3.3.2 查询数据并导入游标(不包含主键)

>>> cur.execute('select sname,score from user_student')
6


补充:
1) 这里以查询 user_student 表里 sname 字段和 socre 字段的所有数据并导入 cur 游标为例
2) 这里查出的数据总共有 6 条

3.3.3 将游标里的数据导入到变量里(不包含主键)
>>> cs = cur.fetchall()

(补充:这里以将数据导入到 cs 变量里为例)

3.3.4 将游标里的数据以对象的形式显示出来(不包含主键)
>>> print(cs)
(('zhangsan', 60), ('lisi', 80), ('wangwu', 90), ('zhaoliu', 70), ('xueer', 70), ('huangyi', 70))

(补充:这里显示出来的是对象)

3.2.5 将游标里的数据以列表的形式显示出来(不包含主键)
>>> for c in cs:
...     print(c)
... 
('zhangsan', 60)
('lisi', 80)
('wangwu', 90)
('zhaoliu', 70)
('xueer', 70)
('huangyi', 70)

(补充:这里显示出来的是列表)

3.2.5 关闭游标(不包含主键)
>>> cur.close()

(补充:这里以关闭 cur 游标为例)

3.3 Django SQL 语句部分查询(只查询 1 条数据)

3.3.1 创建游标(只查询 1 条数据)
>>> cur = connection.cursor()

(补充:这里以创建名为 cur 的游标为例)

3.3.2 查询数据并导入游标(只查询 1 条数据)
>>> cur.execute('select * from user_clazz where id=1')
1


补充:
1) 这里以查询 user_clazz 表里 id 字段的值为 1 为例
2) 这里查出的数据总共有 1 条

3.3.4 将游标里的数据以对象的形式显示出来(只查询 1 条数据)
>>> cur.fetchone()
(1, 'Class1')

(补充:这里显示出来的是列表)

3.2.5 关闭游标(只查询 1 条数据)
>>> cur.close()

(补充:这里以关闭 cur 游标为例)

[实验] Django 最大值、最小值、平均值等特殊数值的数据查询

注意:

本实验是接着 《Django 自定义逻辑添加(通过自定义 save 对象实现)(一次性完成多对多表数据的插入)》而继续的

正文:

步骤一:进入相应的 Django 环境

(django_env) [root@python mysite]# python3
>>> import os,django
>>> os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings")
'mysite.settings'
>>> django.setup()
>>> from user.models import *

步骤二:插入测试数据

>>> user = Student(sname='zhangsan',score=60,cls=Clazz(cname='Class1'))
>>> user.save()

>>> user = Student(sname='lisi',score=80,cls=Clazz(cname='Class1'))
>>> user.save()

>>> user = Student(sname='wangwu',score=90,cls=Clazz(cname='Class1'))
>>> user.save()

>>> user = Student(sname='zhaoliu',score=70,cls=Clazz(cname='Class1'))
>>> user.save()

>>> user = Student(sname='xueer',score=70,cls=Clazz(cname='Class2'))
>>> user.save()

>>> user = Student(sname='huangyi',score=70,cls=Clazz(cname='Class2'))
>>> user.save()

(补充:这里以随机插入 6 条测试数据为例)

步骤三:设置 1 个显示上 1 句 SQL 语句的函数

>>> def showsql():
...     from django.db import connection
...     print(connection.queries[-1]['sql'])

(补充:这里的 [-1] 是指显示上一条操作的 SQL 语句)

步骤四:通过聚合函数查询所需的数值

4.1 通过聚合函数查询最大值

4.1.1 导入聚合函数最大值模块
>>> from django.db.models import Max
4.1.2 通过聚合函数查询最大值(显示默认解释说明)
4.1.2.1 通过聚合函数查询最大值(显示默认解释说明)
>>> Student.objects.aggregate(Max('score'))
{'score__max': 90}


补充:
1) 这里以查询所有数据 score 字段的最大值为例
2) 这里查出的最大值是 90

4.1.2.2 显示通过聚合函数查询最大值的 SQL 语句(显示默认解释说明)
>>> showsql()
SELECT MAX(`user_student`.`score`) AS `score__max` FROM `user_student`

(补充:这里以查询所有数据 score 字段的最大值为例)

4.1.3 通过聚合函数查询最大值(显示自定义解释说明)
4.1.3.1 通过聚合函数查询最大值(显示自定义解释说明)
>>> Student.objects.aggregate(m=Max('score'))
{'m': 90}


补充:
1) 这里以查询所有数据 score 字段的最大值为例
2) 查出的最大值是 90
3) 这里显示的自定义解释说明是 m

4.1.3.2 显示通过聚合函数查询最大值的 SQL 语句(显示自定义解释说明)
>>> showsql()
SELECT MAX(`user_student`.`score`) AS `m` FROM `user_student`


补充:
1) 这里以查询所有数据 score 字段的最大值为例
2) 这里显示的自定义解释说明是 m

4.2 通过聚合函数查询最小值

4.2.1 导入聚合函数最小值模块
>>> from django.db.models import Min
4.2.2 通过聚合函数查询最小值
>>> Student.objects.aggregate(Min('score'))
{'score__min': 60}


补充:
1) 这里以查询所有数据 score 字段的最小值为例
2) 这里查出的最小值是 60

4.2.3 显示通过聚合函数查询最小值的 SQL 语句
>>> showsql()
SELECT MIN(`user_student`.`score`) AS `score__min` FROM `user_student`

(补充:这里以查询所有数据 score 字段的最小值为例)

4.3 通过聚合函数统计数据条数

4.3.1 导入聚合函数统计数据条数的模块
>>> from django.db.models import *
4.3.2 通过聚合函数统计数据条数(统计所有数据的条数)
4.3.2.1 通过聚合函数统计数据条数(统计所有数据的条数)
>>> Student.objects.aggregate(c=Count('*'))
{'c': 6}


补充:
1) 这里统计所有数据的数据总条数为例
2) 这里显示的自定义解释说明是 c
3) 这里查出的数据条数是 6

4.3.2.2 显示通过聚合函数统计数据条数的 SQL 语句(统计所有数据的条数)
>>> showsql()
SELECT COUNT(*) AS `c` FROM `user_student`


补充:
1) 这里统计所有数据的数据总条数为例
2) 这里显示的自定义解释说明是 c

4.3.3 通过聚合函数统计数据条数(统计包含某字段数据的条数)
4.3.3.1 通过聚合函数统计数据条数(统计包含某字段数据的条数)
>>> Student.objects.aggregate(c=Count('score'))
{'c': 6}


补充:
1) 这里以统计包含 score 字段的数据总条数为例
2) 这里显示的自定义解释说明是 c
3) 这里查出的数据条数是 6

4.3.3.2 显示通过聚合函数统计数据条数的 SQL 语句(统计包含某字段数据的条数)
>>> showsql()
SELECT COUNT(`user_student`.`score`) AS `c` FROM `user_student`


补充:
1) 这里以统计包含 score 字段的数据总条数为例
2) 这里显示的自定义解释说明是 c

4.4 通过聚合函数求和

4.4.1 导入聚合函数求和的模块
>>> from django.db.models import *
4.4.2 通过聚合函数求和
>>> Student.objects.aggregate(Sum('score'))
{'score__sum': 440}


补充:
1) 这里以求所有数据 score 字段的值的和为例
2) 这里求出的和是 440

4.4.3 显示通过聚合函数求和的 SQL 语句
>>> showsql()
SELECT SUM(`user_student`.`score`) AS `score__sum` FROM `user_student`

(补充:这里以求所有数据 score 字段的值的和为例)

4.5 通过聚合函数求平均数

4.5.1 导入聚合函数求平均数的模块
>>> from django.db.models import *
4.5.2 通过聚合函数求平均值
>>> Student.objects.aggregate(Avg('score'))
{'score__avg': 73.3333}


补充:
1) 这里以求所有数据 score 字段的平均值为例
2) 这里求出的平均值是 73.3333

4.5.3 显示通过聚合函数求平均值的 SQL 语句
>>> showsql()
SELECT AVG(`user_student`.`score`) AS `score__avg` FROM `user_student`

(补充:这里以求所有数据 score 字段的平均值为例)

步骤五:通过分组聚合函数查询所需的数值

5.1 导入分组聚合函数模块

>>> from django.db.models import *

5.2 通过分组聚合函数统计每组数据的条数

5.2.1 通过分组聚合函数统计每组数据的条数
>>> Student.objects.values('cls').annotate(c=Count('score'))
<QuerySet [{'cls': 1, 'c': 4}, {'cls': 2, 'c': 2}]>


补充:
1) 这里以 cls 字段进行分组,统计每组包含 score 字段数据的条数为例
2) 这里显示的自定义解释说明是 c
3) 这里求出 cls 字段值为 1 的组包含 score 字段的数据有 4 条,cls 字段的值为 2 的组包含 score 字段的数据有 2 条

5.2.2 显示通过分组聚合函数统计每组数据条数的 SQL 语句
>>> showsql()
SELECT `user_student`.`cls_id`, COUNT(`user_student`.`score`) AS `c` FROM `user_student` GROUP BY `user_student`.`cls_id` ORDER BY NULL LIMIT 21


补充:
1) 这里以 cls 字段进行分组,统计每组包含 score 字段数据的条数为例
2) 这里显示的自定义解释说明是 c

5.3 通过分组聚合函数统计求每组数据的平均值

5.3.1 通过分组聚合函数统计求每组数据的平均值
>>> Student.objects.values('cls').annotate(a=Avg('score'))
<QuerySet [{'cls': 1, 'a': 75.0}, {'cls': 2, 'a': 70.0}]>


补充:
1) 这里以 cls 字段进行分组,求每组数据 score 字段的平均值为例
2) 这里显示的自定义解释说明是 a
3) 这里求出 cls 字段值为 1 的组 score 字段的平均值为 75.0,cls 字段的值为 2 的组 score 字段的平均值为 70.0

5.3.2 显示通过分组聚合函数统计求每组数据的平均值的 SQL 语句
>>> showsql()
SELECT `user_student`.`cls_id`, AVG(`user_student`.`score`) AS `a` FROM `user_student` GROUP BY `user_student`.`cls_id` ORDER BY NULL LIMIT 21


补充:
1) 这里以 cls 字段进行分组,求每组数据 score 字段的平均值为例
2) 这里显示的自定义解释说明是 a

步骤六:通过子查询查询所需的数值

6.1 导入子查询模块

>>> from django.db.models import *

6.2 通过子查询查询总值最大的 1 组数据的总值

6.2.1 通过子查询查询总值最大的 1 组数据的总值
>>> Student.objects.values('cls').annotate(s=Sum('score')).aggregate(m=Max('s'))
{'m': 300}


补充:
1) 这里以 cls 字段进行分组,求每组数据 score 字段的总值,再将其求和为例
2) 这里显示的自定义解释说明是 m
3) 这里求出 score 字段的总值为 300
4) values 和 annotate 一起使用时 values 则发挥的是 group by 的作用
5) values 单独使用时 values 发挥的是部分查询的作用

6.2.2 显示通过子查询查询总值最大的 1 组数据总值的 SQL 语句
>>> showsql()
SELECT MAX(`s`) FROM (SELECT `user_student`.`cls_id` AS Col1, SUM(`user_student`.`score`) AS `s` FROM `user_student` GROUP BY `user_student`.`cls_id` ORDER BY NULL) subquery


补充:
1) 这里以 cls 字段进行分组,求每组数据 score 字段的总值,再将其求和为例
2) 这里显示的自定义解释说明是 m
3) values 和 annotate 一起使用时 values 则发挥的是 group by 的作用
4) values 单独使用时 values 发挥的是部分查询的作用

步骤七:通过关联查询查询所需的数值

7.1 导入关联查询模块

>>> from django.db.models import *

7.2 通过关联查询查询关联的数据

7.2.1 通过关联查询查询关联的数据(查询数据表中的非外键字段)
7.2.1.1 通过关联查询查询关联的数据(查询数据表中的非外键字段)
>>> Student.objects.values('cls__cname')
<QuerySet [{'cls__cname': 'Class1'}, {'cls__cname': 'Class1'}, {'cls__cname': 'Class1'}, {'cls__cname': 'Class1'}, {'cls__cname': 'Class2'}, {'cls__cname': 'Class2'}]>


补充:
1) 这里查出了 4 条 cls__cname 为 Class1 的数据和 2 条 cls__cname 为 Class 2 的数据
2) 这里的 cls 是 Django 数据模型类中两张数据表的外键字段,但是 cname 并不是数据库中两张数据表的外键字段

7.2.1.2 通过关联查询查询关联数据的 SQL 语句(查询数据表中的非外键字段)
>>> showsql()
SELECT `user_clazz`.`cname` FROM `user_student` INNER JOIN `user_clazz` ON (`user_student`.`cls_id` = `user_clazz`.`id`) LIMIT 21

(补充:这里的 cls_id 是 user_student 表中关联 user_clazz 表中 id 字段的外键字段)

7.2.2 通过关联查询查询关联的数据(查询数据表中的外键字段)
7.2.2.1 通过关联查询查询关联的数据(查询数据表中的外键字段)
>>> Student.objects.values('cls__id')
<QuerySet [{'cls__id': 1}, {'cls__id': 1}, {'cls__id': 1}, {'cls__id': 1}, {'cls__id': 2}, {'cls__id': 2}]>


补充:
1) 这里查出了 4 条 cls__id 为 1 的数据和 2 条 cls__id 为 2 的数据
2) 这里的 cls 是 Django 数据模型类中两张数据表的外键字段,并且 id 也是数据库中两张数据表的外键字段

7.2.2.2 通过关联查询查询关联数据的 SQL 语句(查询数据表中的外键字段)
>>> showsql()
SELECT `user_student`.`cls_id` FROM `user_student` LIMIT 21

(补充:这里的 cls_id 是 user_student 表中关联 user_clazz 表中 id 字段的外键字段)

步骤八:退出相应的 Django 环境

>>> quit()

步骤九:Django 聚合函数查询、分组聚合函数查询、子查询、关联查询的总结

1) 单独用 aggregate 则代表单独使用聚合函数
2) 单独用 annotate 则代表单独使用分组聚合函数
3) 在 annotate 前面加上 values 则是指定某一个字段进行分组,values.annotate

[实验] Django 自定义逻辑添加 (通过自定义 save 对象实现) (一次性完成多对多表数据的插入)

注意:

文中的 python 系统名、mysite 项目、user 应用 Clazz 类和 Student 类只是站主在本次操作中随意取的名称,读者可以根据自己的喜好换成任意别的名称

正文:

步骤一:系统环境要求

1) 服务器的系统需要是 openSUSE 15.2 版本
2) 服务器要关闭防火墙
3) 服务器系统要配置好可用的软件源(最好是软件数量最多的官方版本)
4) 服务器要能够连接外网

步骤二:安装 Django

2.1 安装 Python3

[root@python ~]# zypper -n install python3

2.2 创建并进入 Django 项目的目录

[root@python ~]# mkdir project
[root@python ~]# cd project

2.3 将 Django 项目的目录指定为 Django 环境

[root@python project]# python3 -m venv django_env

2.4 进入 Django 环境

[root@python project]# source django_env/bin/activate
(django_env) [root@python project]# pip install django

(补充:在此次操作发生时,最新的 Django 版本是 3.2)

步骤三:创建 mysite 项目

3.1 创建 mysite 项目

(django_env) [root@python project]# django-admin startproject mysite

3.2 mysite 项目的目录

3.2.1 安装 tree 目录显示软件
(django_env) [root@python project]# zypper -n install tree
3.2.2 显示 mysite 项目的目录
(django_env) [root@python project]# cd mysite
(django_env) [root@python mysite]# tree
.
├── manage.py
└── mysite
    ├── __init__.py
    ├── asgi.py
    ├── settings.py
    ├── urls.py
    └── wsgi.py

1 directory, 5 files
3.2.3 Django 项目目录介绍

1) mysite 此 Django 项目的容器
2) manage.py 命令行工具,与 Django 项目进行交互
3) mysite/__init__.py 空文件,通知 Python 此项目是 1 个 Python 包
4) mysite/settings.py 此 Django 项目的配置文件
5) mysite/urls.py 此 Django 项目的 URL 声明和 Django 的网站“目录”
6) mysite/wsgi.py WSGI 兼容 Web 服务器的入口

步骤四:创建 user 应用

4.1 创建 user 应用

(django_env) [root@python mysite]# django-admin startapp user

4.2 user 应用的目录

4.2.1 显示 user 应用的目录
(django_env) [root@python mysite]# tree
.
├── manage.py
├── mysite
│   ├── __init__.py
│   ├── asgi.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
└── user
    ├── __init__.py
    ├── admin.py
    ├── apps.py
    ├── migrations
    │   └── __init__.py
    ├── models.py
    ├── tests.py
    └── views.py

3 directories, 13 files
4.2.2 Django 应用目录介绍

1) user/app.py 此 Django 应用的容器
2) user/__init__.py 空文件,通知 Python 此项目是 1 个 Python 包
3) user/admin.py 此 Django 应用自带的后台管理相关的类
4) user/app.py 此 Django 应用指定应用名的文件
5) user/migrations.py 此 Django 应用通过 python 代码生成数据库表时里面会产生一些迁移文件
6) user/models.py 可以在里面创建一些 Python 对象并通过这些对象在数据库里创建对应的表
7) user/test.py 此 Django 应用的测试文档
8) user/views.py 此 Django 应用的视图,接收前端数据,把数据传递给后端,响应相关页面

4.3 在 mysite 应用中导入 user 应用

在 mysite/mysite/settings.py 中添加以下内容:

......
INSTALLED_APPS = [
......
    'user',
]
......

步骤五:实现 user 应用的层级多链接

创建 mysite/user/urls.py 并添加以下内容:

......
from django.conf.urls import url, include
......
mysite.mysite.urls.py
......
urlpatterns = [
......
    url(r'^register/', include('user.urls')),
]

(补充:这里以设置 /register/ 链接对应 user 应用的链接为例)

步骤六:实现连接 MariaDB 数据库

6.1 安装 MairaDB 数据库和客户端

(django_env) [root@python mysite]# zypper -n install mariadb mariadb-devel mariadb-server mariadb-client

6.2 创建用于 Django 的 MairaDB 的库和用户

6.2.1 进入 MairaDB 数据库
(django_env) [root@python mysite]# mysql -h 127.0.0.1 -p
6.2.2 创建用于 Django 的库
MariaDB [(none)]> create database user;

(补充:这里以创建 user 库为例)

6.2.3 创建用于 Django 的用户
MariaDB [(none)]> GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'password' WITH GRANT OPTION;

(补充:这里以创建 root 用户,密码是 password 为例)

6.2.4 刷新权限
MariaDB [(none)]> flush privileges;

6.3 退出 MariaDB 数据库

MariaDB [(none)]> exit

6.4 重启 MariaDB

(django_env) [root@python mysite]# systemctl restart mariadb

步骤七:搭建用于 Django 的 MariaDB 数据库环境

7.1 安装 Django 连接 MariaDB 的模块

(django_env) [root@python mysite]# pip3 install hexdump
(django_env) [root@python mysite]# pip3 install pymysql

7.2 在 mysite 应用中添加 Django 连接 MariaDB 的模块

在 mysite/mysite/init.py 中添加以下内容:

import pymysql
pymysql.install_as_MySQLdb()

7.3 在 user 应用数据库模板中添加 Clazz 类、Student 类和插入多对多数据的函数

在 mysite/user/models.py 中添加以下内容:

......
class Clazz(models.Model):
    cname = models.CharField(max_length=30)

class Student(models.Model):
    sname = models.CharField(max_length=30)
    score = models.PositiveBigIntegerField()
    cls = models.ForeignKey(Clazz,on_delete=models.CASCADE)

    def __str__(self):
        return u'Student:%s,%s'%(self.sname,self.score)

    def save(self, force_insert=False, force_update=False, using=None, update_fields=None):
        try:
            self.cls = Clazz.objects.get(cname=self.cls.cname)
        except Clazz.DoesNotExist:
            self.cls = Clazz.objects.create(cname=self.cls.cname)

        #Insertion of student table
        models.Model.save(self, force_insert=False, force_update=False,using=None, update_fields=None)


补充:
1) models.ForeignKey(Clazz,on_delete=models.CASCADE) 会生成一个属于 Clazz 表的 id,user_class 表中会生成一个 cls_id 字段,这个字段是 Clazz 表中的 id 字段的外键
2) 这里以创建一次性完成多对多表数据的插入的 save 对象为例

7.4 在 mysite 应用中设置连接到 MariaDB 数据库

将 mysite/mysite/settings.py 中的以下内容:

......
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'db.sqlite3',
    }
}
......

修改为:

......
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'user',
        'HOST': '127.0.0.1',
        'PORT': '3306',
        'USER': 'root',
        'PASSWORD': 'password',
    }
}
......


补充:这里以
1) 使用的库是 user
2) 使用的服务器是 127.0.0.1
3) 使用的端口是 3306
4) 使用的用户是 root
5) 使用的密码是 password
为例

7.5 生成牵引文件

(django_env) [root@python mysite]# python3 manage.py makemigrations
Migrations for 'user':
  user/migrations/0001_initial.py
    - Create model Clazz
    - Create model Student

7.6 将牵引文件导入 MariaDB 数据库

(django_env) [root@python mysite]# python3 manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, sessions, user
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 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 auth.0012_alter_user_first_name_max_length... OK
  Applying sessions.0001_initial... OK
  Applying user.0001_initial... OK

步骤八:一次性完成多对多表数据的插入

8.1 进入相应的 Django 环境

(django_env) [root@python mysite]# python3
>>> import os,django
>>> os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings")
'mysite.settings'
>>> django.setup()
>>> from user.models import *

8.2 一次性完成多对多表数据的插入

>>> user = Student(sname='zhangsan',score=60,cls=Clazz(cname='Class1'))
>>> user.save()

8.3 退出相应的 Django 环境

>>> quit()