[实验] Django 自定义查询 (通过自定义 manager 管理器实现)

注意:

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

正文:

步骤目录:

步骤一:系统环境要求

步骤二:安装 Django
2.1 安装 Python3
2.2 创建并进入 Django 项目的目录
2.3 将 Django 项目的目录指定为 Django 环境
2.4 进入 Django 环境

步骤三:创建 mysite 项目
3.1 创建 mysite 项目
3.2 mysite 项目的目录
3.2.1 安装 tree 目录显示软件
3.2.2 显示 mysite 项目的目录
3.2.3 Django 项目目录介绍

步骤四:创建 test 应用
4.1 创建 test 应用
4.2 test 应用的目录
4.2.1 显示 test 应用的目录
4.2.2 Django 应用目录介绍
4.3 在 mysite 应用中导入 test 应用

步骤五:实现连接 MariaDB 数据库
5.1 安装 MairaDB 数据库和客户端
5.2 创建用于 Django 的 MairaDB 的库和用户
5.2.1 进入 MairaDB 数据库
5.2.2 创建用于 Django 的库
5.2.3 创建用于 Django 的用户
5.2.4 刷新权限
5.3 退出 MariaDB 数据库
5.4 重启 MariaDB

步骤六:搭建用于 Django 的 MariaDB 数据库环境
6.1 安装 Django 连接 MariaDB 的模块
6.2 在 mysite 应用中添加 Django 连接 MariaDB 的模块
6.3 在 test 应用数据库模板中添加 Student 类
6.4 在 mysite 应用中设置连接到 MariaDB 数据库
6.5 生成牵引文件
6.6 将牵引文件导入 MariaDB 数据库

步骤七:插入测试数据
7.1 进入相应的 Django 环境
7.2 插入测试数据
7.3 退出相应的 Django 环境

步骤八:正常查询数据
8.1 进入相应的 Django 环境
8.2 正常查询数据
8.3 退出相应的 Django 环境

步骤九:通过自定义 manager 管理器查询数据
9.1 自定义 manager 管理器(通过重写父类的 all 实现)
9.1.1 自定义一个查询 isdelete=True 数据的 manager 管理器
9.1.1.1 创建一个自定义 manager 管理器的类
9.1.1.2 进入相应的 Django 环境
9.1.1.3 通过自定义 manager 管理器查询数据
9.1.1.4 退出相应的 Django 环境
9.1.2 自定义一个查询 isdelete=False 数据的管理器
9.1.2.1 创建一个自定义 manager 管理器的类
9.1.2.2 进入相应的 Django 环境
9.1.2.3 通过自定义 manager 管理器查询数据
9.1.2.4 退出相应的 Django 环境
9.2 自定义管理器(通过重写继承的子类 get_queryset 实现)
9.2.1 创建一个自定义 manager 管理器的类
9.2.2 进入相应的 Django 环境
9.2.3 通过自定义 manager 管理器查询数据
9.2.4 退出相应的 Django 环境

具体的操作步骤:

步骤一:系统环境要求

(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 此项目是一个 Python 包
(4)mysite/settings.py 此 Django 项目的配置文件
(5)mysite/urls.py 此 Django 项目的 URL 声明和 Django 的网站“目录”
(6)mysite/wsgi.py WSGI 兼容 Web 服务器的入口

步骤四:创建 test 应用
4.1 创建 test 应用

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

4.2 test 应用的目录
4.2.1 显示 test 应用的目录

(django_env) [root@python mysite]# tree
.
├── manage.py
├── mysite
│   ├── __init__.py
│   ├── asgi.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
└── test
    ├── __init__.py
    ├── admin.py
    ├── apps.py
    ├── migrations
    │   └── __init__.py
    ├── models.py
    ├── tests.py
    └── views.py

3 directories, 13 files

4.2.2 Django 应用目录介绍

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

4.3 在 mysite 应用中导入 test 应用

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

......
INSTALLED_APPS = [
......
    'test',
]
......

步骤五:实现连接 MariaDB 数据库
5.1 安装 MairaDB 数据库和客户端

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

5.2 创建用于 Django 的 MairaDB 的库和用户
5.2.1 进入 MairaDB 数据库

(django_env) [root@python mysite]# mysql -h 127.0.0.1 -p

5.2.2 创建用于 Django 的库

MariaDB [(none)]> create database user;

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

5.2.3 创建用于 Django 的用户

MariaDB [(none)]> GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'password' WITH GRANT OPTION;

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

5.2.4 刷新权限

MariaDB [(none)]> flush privileges;

5.3 退出 MariaDB 数据库

MariaDB [(none)]> exit

5.4 重启 MariaDB

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

步骤六:搭建用于 Django 的 MariaDB 数据库环境
6.1 安装 Django 连接 MariaDB 的模块

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

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

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

import pymysql
pymysql.install_as_MySQLdb()

6.3 在 test 应用数据库模板中添加 Student 类

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

class Student(models.Model):
    sname = models.CharField(max_length=30)
    isdelete = models.BooleanField(default=False)

(补充:这里以创建包含 sname 字段和 isdelete 字段的 Student 类为例)

6.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': 'test',
        'HOST': '127.0.0.1',
        'PORT': '3306',
        'USER': 'root',
        'PASSWORD': 'password',
    }
}
......


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

6.5 生成牵引文件

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

6.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

步骤七:插入测试数据
7.1 进入相应的 Django 环境

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

7.2 插入测试数据

>>> Student.objects.create(sname='zhangsan')
<Student: Student object (1)>

>>> Student.objects.create(sname='lisi',isdelete=True)
<Student: Student object (2)>

>>> Student.objects.create(sname='wangwu',isdelete=True)
<Student: Student object (3)>

(补充:这里以往 Student 类任意插入三条测试数据为例)

7.3 退出相应的 Django 环境

>>> quit();

步骤八:正常查询数据
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 test.models import *

8.2 正常查询数据

>>> Student.objects.all()
<QuerySet [<Student: Student object (1)>, <Student: Student object (2)>, <Student: Student object (3)>]>

(补充:此时会一次性查询出 Student 类里所有的数据)

8.3 退出相应的 Django 环境

>>> quit();

步骤九:通过自定义 manager 管理器查询数据
9.1 自定义 manager 管理器(通过重写父类的 all 实现)
9.1.1 自定义一个查询 isdelete=True 数据的 manager 管理器
9.1.1.1 创建一个自定义 manager 管理器的类

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

......
class Student(models.Model):
    sname = models.CharField(max_length=30)
    isdelete = models.BooleanField(default=False)
......

修改为:

......
from django.db.models.manager import Manager

class CustomManager(Manager):
    def all(self):
        return Manager.all(self).filter(isdelete=True)

class Student(models.Model):
    sname = models.CharField(max_length=30)
    isdelete = models.BooleanField(default=False)

    objects = CustomManager()

    def __str__(self):
        return u'student:%s'%self.isdelete
......


补充:
(1)self 在 python 中代表当前对象,在其他语言中,会用 this 来代表当前对象
(2)这里以将父类的 all 重写成只选择 isdelete=True 数据的 CustomManager(Manager) 类并在 Student 类中使用 objects 调用为例

9.1.1.2 进入相应的 Django 环境

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

9.1.1.3 通过自定义 manager 管理器查询数据

>>> Student.objects.all()
<QuerySet [<Student: student:True>, <Student: student:True>]>

(补充:这里只查出了 isdelete=True 的数据)

9.1.1.4 退出相应的 Django 环境

>>> quit();

9.1.2 自定义一个查询 isdelete=False 数据的 manager 管理器
9.1.2.1 创建一个自定义 manager 管理器的类

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

......
from django.db.models.manager import Manager

class CustomManager(Manager):
    def all(self):
        return Manager.all(self).filter(isdelete=True)

class Student(models.Model):
    sname = models.CharField(max_length=30)
    isdelete = models.BooleanField(default=False)

    objects = CustomManager()

    def __str__(self):
        return u'student:%s'%self.isdelete
......

修改为:

......
from django.db.models.manager import Manager

class CustomManager(Manager):
    def all(self):
        return Manager.all(self).filter(isdelete=True)

class NotDeletedManager(Manager):
    def all(self):
        return Manager.all(self).filter(isdelete=False)

class Student(models.Model):
    sname = models.CharField(max_length=30)
    isdelete = models.BooleanField(default=False)

    objects = CustomManager()

    show = NotDeletedManager()

    def __str__(self):
        return u'student:%s'%self.isdelete
......

(补充:这里以添加一个将父类的 all 重写成只选择 isdelete=False 数据的 NotDeletedManager(Manager) 对象并在 Student 类中使用 show 调用为例)

9.1.2.2 进入相应的 Django 环境

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

9.1.2.3 通过自定义 manager 管理器查询数据

>>> Student.show.all()
<QuerySet [<Student: student:False>]>

(补充:这里只查出了 isdelete=False 的数据)

9.1.2.4 退出相应的 Django 环境

>>> quit();

9.2 自定义 manager 管理器(通过重写继承的子类 get_queryset 实现)
9.2.1 创建一个自定义 manager 管理器的类

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

......
from django.db.models.manager import Manager

class CustomManager(Manager):
    def all(self):
        return Manager.all(self).filter(isdelete=True)

class NotDeletedManager(Manager):
    def all(self):
        return Manager.all(self).filter(isdelete=False)
   
class Student(models.Model):
    sname = models.CharField(max_length=30)
    isdelete = models.BooleanField(default=False)

    objects = CustomManager()

    show = NotDeletedManager()

    def __str__(self):
        return u'student:%s'%self.isdelete
......

修改为:

......
from django.db.models.manager import Manager

class CustomManager(Manager):
    #def all(self):
    #    return Manager.all(self).filter(isdelete=True)

    def get_queryset(self):
        return Manager.get_queryset(self).filter(isdelete=True)

class NotDeletedManager(Manager):
    def all(self):
        return Manager.all(self).filter(isdelete=False)
   
class Student(models.Model):
    sname = models.CharField(max_length=30)
    isdelete = models.BooleanField(default=False)

    objects = CustomManager()

    show = NotDeletedManager()

    def __str__(self):
        return u'student:%s'%self.isdelete
......

(补充:这里以添加一个将子类的 get_queryset 重写成只选择 isdelete=True 数据的 CustomManager(Manager) 对象并在 Student 类中使用 objects 调用为例)

9.2.2 进入相应的 Django 环境

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

9.2.3 通过自定义 manager 管理器查询数据

>>> Student.objects.all()
<QuerySet [<Student: student:True>, <Student: student:True>]>

(补充:这里只查出了 isdelete=True 的数据)

9.2.4 退出相应的 Django 环境

>>> quit();

[实验] Django 数据展示 (多对多版)

注意:

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

正文:

步骤一:系统环境要求

步骤二:安装 Django
2.1 安装 Python3
2.2 创建并进入 Django 项目的目录
2.3 将 Django 项目的目录指定为 Django 环境
2.4 进入 Django 环境

步骤三:创建 mysite 项目
3.1 创建 mysite 项目
3.2 mysite 项目的目录
3.2.1 安装 tree 目录显示软件
3.2.2 显示 mysite 项目的目录
3.2.3 Django 项目目录介绍

步骤四:创建 user 应用
4.1 创建 user 应用
4.2 user 应用的目录
4.2.1 显示 user 应用的目录
4.2.2 Django 应用目录介绍
4.3 在 mysite 应用中导入 user 应用

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

步骤六:实现连接 MariaDB 数据库
6.1 安装 MairaDB 数据库和客户端
6.2 创建用于 Django 的 MairaDB 的库和用户
6.2.1 进入 MairaDB 数据库
6.2.2 创建用于 Django 的库
6.2.3 创建用于 Django 的用户
6.2.4 刷新权限
6.3 退出 MariaDB 数据库
6.4 重启 MariaDB

步骤七:搭建用于 Django 的 MariaDB 数据库环境
7.1 安装 Django 连接 MariaDB 的模块
7.2 在 mysite 应用中添加 Django 连接 MariaDB 的模块
7.3 在 user 应用数据库模板中添加 Clazz 类、Course 类、Student 类和插入多对多数据的对象
7.4 在 mysite 应用中设置连接到 MariaDB 数据库
7.5 生成牵引文件
7.6 将牵引文件导入 MariaDB 数据库

步骤八:实现多对多注册功能
8.1 创建所需的 HTML 模版
8.1.1 在 user 应用中添加一个学生注册功能的 HTML 模板
8.1.2 在 user 应用中添加一个显示所有数据的 HTML 模板
8.1.3 在 user 应用中添加一个显示某一条 course 数据详细内容的 HTML 模板
8.2 在 user 应用中添加一个网页返回值的模块并实现所需功能
8.3 在 movies 应用中添加一个链接并设置对应的模块

步骤九:启动 Django 服务

步骤十:测试页码功能

步骤目录:

步骤一:系统环境要求

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 此项目是一个 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 此项目是一个 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/mysite/urls.py 中添加以下内容:

......
from django.conf.urls import url, include
......
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 类、Course 类、Student 类和插入多对多数据的对象

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

class Clazz(models.Model):
    cno = models.AutoField(primary_key=True)
    cname = models.CharField(max_length=30)

    def __str__(self):
        return u'Clazz:%s'%self.cname

class Course(models.Model):
    course_no = models.AutoField(primary_key=True)
    course_name = models.CharField(max_length=30)

    def __str__(self):
        return u'Course:%s'%self.course_name

class Student(models.Model):
    sno = models.AutoField(primary_key=True)
    sname = models.CharField(max_length=30)
    cls = models.ForeignKey(Clazz,on_delete=models.CASCADE)
    cour = models.ManyToManyField(Course)

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

# Get class object according to class name
def getCls(cname):
    try:
        cls = Clazz.objects.get(cname=cname)
    except Clazz.DoesNotExist:
        cls = Clazz.objects.create(cname=cname)
        return cls

def getCourseList(*coursenames):
    courseList = []

    for cn in coursenames:
        try:
            c = Course.objects.get(course_name=cn)
        except Course.DoesNotExist:
            c = Course.objects.create(course_name=cn)
        courseList.append(c)

    return courseList

def registerStu(sname,cname,*coursenames):
    #1. Get class objects
    cls = getCls(cname)
    #2. Gets the list of course objects
    courseList = getCourseList(*coursenames)
    #3. Insert student table data
    try:
        stu = Student.objects.get(sname=sname)
    except Student.DoesNotExist:
        stu = Student.objects.create(sname=sname,cls=cls)
    #4. Insert intermediate table data
    stu.cour.add(*courseList)

    return True


补充:
1) 这里 getCls 对象的作用是获取 cname 变量,如果数据库中没有 cname 变量的值则直接插入这个值
2) 这里 getCourseList 对象的作用是获取 coursenames 变量,如果数据库中没有 coursenames 变量的值则直接插入这个值
3) 这里 registerStu 对象的作用是执行 getCls 对象和 getCourseList 对象,获取 sname 变量,如果数据库中没有 sname 变量的值则直接插入这个值

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 Course
    - 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

(补充:此时会在数据库里生成三张表 user_clazz 表、user_course 表、user_student 表和 user_student_cour 表,其中 user_student_cour 表是 user_course 表和 user_student 表的中间表)

步骤八:实现多对多注册功能
8.1 创建所需的 HTML 模版
8.1.1 在 user 应用中添加一个学生注册功能的 HTML 模板

创建 mysite/user/templates/register.html 并添加以下内容:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>register</title>
</head>
<body>
    <form action="/register/" method="post">
        {% csrf_token %}
        <p>
            <label for="sn">Name: </label><input name="sname" id="sn"/>
        </p>
        <p>
            <label for="sc">Classroom: </label>
            <select name="clsname" id="sc">
                <option value="Class 1">Class 1</option>
                <option value="Class 2">Class 2</option>
                <option value="Class 3">Class 3</option>
            </select>
        </p>
        <p>
            <label for="cour">Course Selection: </label>
            <input type="checkbox" name="coursename" value="Python"/>Python &emsp;
            <input type="checkbox" name="coursename" value="Shell"/>Shell &emsp;
            <input type="checkbox" name="coursename" value="HTML"/>HTML &emsp;
            <input type="checkbox" name="coursename" value="Django"/>Django &emsp;
        </p>
        <p>
            <input type="submit" value="Register"/>
        </p>
    </form>
</body>
</html>


补充:这里以
1) 生成一个用户名输入栏,赋值给 sname
2) 生成一个单选框,赋值给 clsname
3) 生成一个多选框,赋值给 cour
4) 生一个注册按钮
为例

8.1.2 在 user 应用中添加一个显示所有数据的 HTML 模板

创建 mysite/user/templates/showall.html 并添加以下内容:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>register</title>
</head>
<body>

<table border="1" cellspacing="0" width="500px">
    <tr>
        <th>Code</th>
        <th>ClassRoom</th>
        <th>Operation</th>
    </tr>
    {% for c in cls %}
        <tr>
            <td>{{ forloop.counter }}</td>
            <td>{{ c.cname }}</td>
            <td>
                <a href="/register/getstu/?cno={{ c.cno }}">details</a>
            </td>
        <tr>
    {% endfor %}

</table>

</body>
</html>

(补充:这里以生成显示全部数据的列表为例)

8.1.3 在 user 应用中添加一个显示某一条 course 数据详细内容的 HTML 模板

创建 mysite/user/templates/stulist.html 并添加以下内容:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>register</title>
</head>
<body>

<table border="1" cellspacing="0" width="500px">
    <tr>
        <th>Code</th>
        <th>Student Name</th>
        <th>Classroom Name</th>
        <th>Course Name</th>
    </tr>
    {% for stu in stus %}
        <tr>
            <td>{{ forloop.counter }}</td>
            <td>{{ stu.sname }}</td>
            <td>{{ stu.cls.cname }}</td>
            <td>
                {% for st in stu.cour.all %}
                    {{ st.course_name }}
                {% endfor %}
            </td>
        <tr>
    {% endfor %}

</table>

</body>
</html>


补充:
1) 这里以生成显示某一条 Classroom Name 为特定值的所有相关数据为例
2) 这里模版语法 all 后面不用加小括号“()”:

{% for st in stu.cour.all %}

8.2 在 user 应用中添加一个网页返回值的模块并实现所需功能

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

......
from django.shortcuts import render
from .models import *
from django.http import HttpResponse, request
......

def index_view(request):
    if request.method == 'GET':
        return render(request,'register.html')
    else:
        # Receive request parameters
        sname = request.POST.get('sname','')
        cname = request.POST.get('clsname','')
        coursenames = request.POST.getlist('coursename',[])

        # Register data to database
        flag = registerStu(sname,cname,*coursenames)
        if flag:
            return HttpResponse('register success!')
        return HttpResponse('register fale!')

def showall_view(request):
    #Display all classroom informations
    cls = Clazz.objects.all()
    return render(request,'showall.html',{'cls':cls})

def getstu_view(request):
    #Get classroom code
    cno = request.GET.get('cno','')
    mno = int(cno)

    #Get student information from class code
    stus = Clazz.objects.get(cno=mno).student_set.all()

    return render(request,'stulist.html',{'stus':stus})


补充:这里以
1) 获取来自 HTML 的 sanme、clsname 和 coursename 变量
2) 使用 registerStu 对象处理所有变量,处理成功则返回 success! 否则返回 fale!
3) 使用 showall_view 对象将所有数据传递给 showall.html
4) 使用 getstu_view 对象将某一条 Classroom Name 为特定值的所有相关数据传递给 stulist.html
为例

8.3 在 movies 应用中添加一个链接并设置对应的模块

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

from django.conf.urls import url
from user.views import *

urlpatterns=[
    url(r'^$',index_view),
    url(r'^showall/$',showall_view),
    url(r'^getstu/$',getstu_view),
]

(补充:这里以设置空链接链接对应 index_view 模块为例)

步骤九:启动 Django 服务

(django_env) [root@python mysite]# python3 manage.py runserver

步骤十:测试页码功能

1) 打开浏览器输入以下网址:

http://127.0.0.1:8000/register/

2) 可以看到 Name 输入栏、Classroom 单选框、Course Selection 多选框和 Register 注册按钮,并可以注册信息

3) 打开浏览器输入以下网址:

http://127.0.0.1:8000/showall/

4) 可以看到刚才注册的信息并且还有链接看到详细内容

[实验] Django 注册功能的实现 (多对多版)

注意:

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

步骤目录:

步骤一:系统环境要求

步骤二:安装 Django
2.1 安装 Python3
2.2 创建并进入 Django 项目的目录
2.3 将 Django 项目的目录指定为 Django 环境
2.4 进入 Django 环境

步骤三:创建 mysite 项目
3.1 创建 mysite 项目
3.2 mysite 项目的目录
3.2.1 安装 tree 目录显示软件
3.2.2 显示 mysite 项目的目录
3.2.3 Django 项目目录介绍

步骤四:创建 user 应用
4.1 创建 user 应用
4.2 user 应用的目录
4.2.1 显示 user 应用的目录
4.2.2 Django 应用目录介绍
4.3 在 mysite 应用中导入 user 应用

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

步骤六:实现连接 MariaDB 数据库
6.1 安装 MairaDB 数据库和客户端
6.2 创建用于 Django 的 MairaDB 的库和用户
6.2.1 进入 MairaDB 数据库
6.2.2 创建用于 Django 的库
6.2.3 创建用于 Django 的用户
6.2.4 刷新权限
6.3 退出 MariaDB 数据库
6.4 重启 MariaDB

步骤七:搭建用于 Django 的 MariaDB 数据库环境
7.1 安装 Django 连接 MariaDB 的模块
7.2 在 mysite 应用中添加 Django 连接 MariaDB 的模块
7.3 在 user 应用数据库模板中添加 Clazz 类、Course 类、Student 类和插入多对多数据的对象
7.4 在 mysite 应用中设置连接到 MariaDB 数据库
7.5 生成牵引文件
7.6 将牵引文件导入 MariaDB 数据库

步骤八:实现多对多注册功能
8.1 在 user 应用中添加一个学生注册功能的 HTML 模板
8.2 在 user 应用中添加一个网页返回值的模块并实现所需功能
8.3 在 user 应用中添加一个链接并设置对应的模块

步骤九:启动 Django 服务

步骤十:测试页码功能

具体的操作步骤:

正文:

步骤一:系统环境要求

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 此项目是一个 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 此项目是一个 python 包
3) muser/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/mysite/urls.py 中添加以下内容:

......
from django.conf.urls import url, include
......
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 类、Course 类、Student 类和插入多对多数据的对象

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

......
class Clazz(models.Model):
    cno = models.AutoField(primary_key=True)
    cname = models.CharField(max_length=30)

    def __str__(self):
        return u'Clazz:%s'%self.cname

class Course(models.Model):
    course_no = models.AutoField(primary_key=True)
    course_name = models.CharField(max_length=30)

    def __str__(self):
        return u'Course:%s'%self.course_name

class Student(models.Model):
    sno = models.AutoField(primary_key=True)
    sname = models.CharField(max_length=30)
    cls = models.ForeignKey(Clazz,on_delete=models.CASCADE)
    cour = models.ManyToManyField(Course)

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

# Get class object according to class name
def getCls(cname):
    try:
        cls = Clazz.objects.get(cname=cname)
    except Clazz.DoesNotExist:
        cls = Clazz.objects.create(cname=cname)
        return cls

def getCourseList(*coursenames):
    courseList = []

    for cn in coursenames:
        try:
            c = Course.objects.get(course_name=cn)
        except Course.DoesNotExist:
            c = Course.objects.create(course_name=cn)
        courseList.append(c)

    return courseList

def registerStu(sname,cname,*coursenames):
    #1. Get class objects
    cls = getCls(cname)
    #2. Gets the list of course objects
    courseList = getCourseList(*coursenames)
    #3. Insert student table data
    try:
        stu = Student.objects.get(sname=sname)
    except Student.DoesNotExist:
        stu = Student.objects.create(sname=sname,cls=cls)
    #4. Insert intermediate table data
    stu.cour.add(*courseList)

    return True


补充:
1) 这里 getCls 对象的作用是获取 cname 变量,如果数据库中没有 cname 变量的值则直接插入这个值
2) 这里 getCourseList 对象的作用是获取 coursenames 变量,如果数据库中没有 coursenames 变量的值则直接插入这个值
3) 这里 registerStu 对象的作用是执行 getCls 对象和 getCourseList 对象,获取 sname 变量,如果数据库中没有 sname 变量的值则直接插入这个值

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 Course
    - 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

(补充:此时会在数据库里生成三张表 user_clazz 表、user_course 表、user_student 表和 user_student_cour 表,其中 user_student_cour 表是 user_course 表和 user_student 表的中间表)

步骤八:实现多对多注册功能
8.1 在 user 应用中添加一个学生注册功能的 HTML 模板

创建 mysite/user/templates/register.html 并添加以下内容:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>register</title>
</head>
<body>
    <form action="/register/" method="post">
        {% csrf_token %}
        <p>
            <label for="sn">Name: </label><input name="sname" id="sn"/>
        </p>
        <p>
            <label for="sc">Classroom: </label>
            <select name="clsname" id="sc">
                <option value="Class 1">Class 1</option>
                <option value="Class 2">Class 2</option>
                <option value="Class 3">Class 3</option>
            </select>
        </p>
        <p>
            <label for="cour">Course Selection: </label>
            <input type="checkbox" name="coursename" value="Python"/>Python &emsp;
            <input type="checkbox" name="coursename" value="Shell"/>Shell &emsp;
            <input type="checkbox" name="coursename" value="HTML"/>HTML &emsp;
            <input type="checkbox" name="coursename" value="Django"/>Django &emsp;
        </p>
        <p>
            <input type="submit" value="Register"/>
        </p>
    </form>
</body>
</html>


补充:这里以
1) 生成一个用户名输入栏,赋值给 sname
2) 生成一个单选框,赋值给 clsname
3) 生成一个多选框,赋值给 cour
4) 生一个注册按钮
为例

8.2 在 user 应用中添加一个网页返回值的模块并实现所需功能

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

......
from django.shortcuts import render
from .models import *
from django.http import HttpResponse, request
......

def index_view(request):
    if request.method == 'GET':
        return render(request,'register.html')
    else:
        # Receive request parameters
        sname = request.POST.get('sname','')
        cname = request.POST.get('clsname','')
        coursenames = request.POST.getlist('coursename',[])

        # Register data to database
        flag = registerStu(sname,cname,*coursenames)
        if flag:
            return HttpResponse('register success!')
        return HttpResponse('register fale!')


补充:这里以
1) 获取来自 HTML 的 sanme、clsname 和 coursename 变量
2) 使用 registerStu 对象处理所有变量,处理成功则返回 success! 否则返回 fale!
为例

8.3 在 user 应用中添加一个链接并设置对应的模块

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

from django.conf.urls import url
from user.views import *

urlpatterns=[
    url(r'^$',index_view)
]

(补充:这里以设置空链接链接对应 index_view 模块为例)

步骤九:启动 Django 服务

(django_env) [root@python mysite]# python3 manage.py runserver

步骤十:测试页码功能

1) 打开浏览器输入以下网址:

http://127.0.0.1:8000/register/

2) 可以看到 Name 输入栏、Classroom 单选框、Course Selection 多选框和 Register 注册按钮

[内容] Python 可变参数和参数解包

内容目录:

内容一:可变参数和参数解包区别

内容二:可变参数的使用案例
2.1 进入 python3 环境
2.2 创建一个输出可变参数内容的对象
2.3 测试输出可变参数内容的对象
2.4 让输出可变参数内容的对象处理元组
2.5 让输出可变参数内容的对象处理元组和字典

内容三:参数解包的使用案例
3.1 进入 python3 环境
3.2 创建一个进行参数解包的对象
3.3 测试进行参数解包的对象
3.4 让进行参数解包的对象处理元组
3.5 让进行参数解包的对象处理字典

具体的内容:

内容一:可变参数和参数解包区别

1) 可变参数是在形参中,通过 * 来实现
2) 参数解包是在实参中,通过 * 来实现

内容二:可变参数的使用案例
2.1 进入 python3 环境

# python3
>>> 

2.2 创建一个输出可变参数内容的对象

>>> def demo(*args,**kwargs):
...     print(args)
...     print(kwargs)
... 


补充:
1) 这里以创建 demo 对象为例
2) 这里一个 * 代表接收的是一个元组,两个 ** 代表接收的是一个键值对从而形成一个字典

2.3 测试输出可变参数内容的对象

>>> demo()
()
{}

(补充:这里两个小括号 “()” 是指元组,两个大括号是 “{}” 是指字典)

2.4 让输出可变参数内容的对象处理元组

>>> demo(1,2,3)
(1, 2, 3)
{}

(补充:这里以处理元组 1,2,3 为例)

2.5 让输出可变参数内容的对象处理元组和字典

>>> demo(1,2,3,c='2')
(1, 2, 3)
{'c': '2'}

(补充:这里以处理元组 1,2,3 和字典 c=’2′ 为例)

内容三:参数解包的使用案例
3.1 进入 python3 环境

# python3
>>> 

3.2 创建一个进行参数解包的对象

>>> def demo(a,b,c):
...     print(a,b,c)
...

3.3 测试进行参数解包的对象

>>> demo(1,2,3)
1 2 3

3.4 让进行参数解包的对象处理元组

>>> args = (1,2,3)
>>> demo(*args)
1 2 3

3.5 让进行参数解包的对象处理字典

>>> kwargs1 = { 'a':'a1','b':'b2','c':'c3'}
>>> demo(**kwargs1)
a1 b2 c3

[实验] Django 多表的实现 (多对多版)

注意:

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

正文:

步骤目录:

步骤一:系统环境要求

步骤二:安装 Django
2.1 安装 Python3
2.2 创建并进入 Django 项目的目录
2.3 将 Django 项目的目录指定为 Django 环境
2.4 进入 Django 环境

步骤三:创建 mysite 项目
3.1 创建 mysite 项目
3.2 mysite 项目的目录
3.2.1 安装 tree 目录显示软件
3.2.2 显示 mysite 项目的目录
3.2.3 Django 项目目录介绍

步骤四:创建 user 应用
4.1 创建 user 应用
4.2 user 应用的目录
4.2.1 显示 user 应用的目录
4.2.2 Django 应用目录介绍
4.3 在 mysite 应用中导入 user 应用

步骤五:实现连接 MariaDB 数据库
5.1 安装 MairaDB 数据库和客户端
5.2 创建用于 Django 的 MairaDB 的库和用户
5.2.1 进入 MairaDB 数据库
5.2.2 创建用于 Django 的库
5.2.3 创建用于 Django 的用户
5.2.4 刷新权限
5.3 退出 MariaDB 数据库
5.4 重启 MariaDB

步骤六:搭建用于 Django 的 MariaDB 数据库环境
6.1 安装 Django 连接 MariaDB 的模块
6.2 在 mysite 应用中添加 Django 连接 MariaDB 的模块
6.3 在 user 应用数据库模板中添加 Course 类和 Teacher
6.4 在 mysite 应用中设置连接到 MariaDB 数据库
6.5 生成牵引文件
6.6 将牵引文件导入 MariaDB 数据库
6.7 查看导入到 MariaDB 数据库的表
6.7.1 进入 MariaDB 数据库
6.7.2 查看所有的库
6.7.3 进入 user 库
6.7.4 查看 user 库里所有的表
6.7.5 查看 user_course 表、user_teacher 表和 user_teacher_cour 表里的数据
6.7.6 查看 user_course 表、user_teacher 表和 user_teacher_cour 的表结构

步骤七:测试 Django 一对多多表
7.1 配置 Django 环境
7.1.1 进入 Python 环境
7.1.2 引入 os 模块和 django 模块
7.1.3 调用 mysite.settings 的配置
7.1.4 让刚刚的调用生效
7.1.5 调用 mysite 项目 user 应用 models 模块里的所有内容
7.2 插入多对多多表数据
7.2.1 往 Course 表插入三条数据(插入三条课程数据)
7.2.2 往 Teacher 表插入两条数据(插入两条老师数据)
7.2.3 让 Teacher 表里的某一条数据关联 Course 表中的三条数据
7.3 查看多对多多表数据
7.3.1 查看多对多多表数据的性质
7.3.2 正向查询数据
7.3.3 逆向查询数据
7.4 使用对象插入一对多多表数据
7.4.1 创建一个插入数据的对象
7.4.2 使用对象插入多对多多表数据

具体的操作步骤:

步骤一:系统环境要求

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 此项目是一个 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 此项目是一个 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',
]
......

步骤五:实现连接 MariaDB 数据库
5.1 安装 MairaDB 数据库和客户端

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

5.2 创建用于 Django 的 MairaDB 的库和用户
5.2.1 进入 MairaDB 数据库

(django_env) [root@python mysite]# mysql -h 127.0.0.1 -p

5.2.2 创建用于 Django 的库

MariaDB [(none)]> create database user;

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

5.2.3 创建用于 Django 的用户

MariaDB [(none)]> GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'password' WITH GRANT OPTION;

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

5.2.4 刷新权限

MariaDB [(none)]> flush privileges;

5.3 退出 MariaDB 数据库

MariaDB [(none)]> exit

5.4 重启 MariaDB

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

步骤六:搭建用于 Django 的 MariaDB 数据库环境
6.1 安装 Django 连接 MariaDB 的模块

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

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

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

import pymysql
pymysql.install_as_MySQLdb()

6.3 在 user 应用数据库模板中添加 Course 类和 Teacher

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

class Course(models.Model):
    course_no=models.AutoField(primary_key=True)
    course_name=models.CharField(max_length=30,)

    def __str__(self):
        return u'Course:%s'%self.course_name

class Teacher(models.Model):
    tno = models.AutoField(primary_key=True)
    tname = models.CharField(max_length=30)
    cour = models.ManyToManyField(Course)

    def __str__(self):
        return u'Teacher:%s'%self.tname


补充:
1) 这里的这条语句会让 Course 类中 course_name 字段以 Course: 的列表形式显示出来:

    def __str__(self):
        return u'Course:%s'%self.course_name

2) 这里的这条语句会让 Teacher 类中 tname 字段以 Teacher: 的列表形式显示出来:

    def __str__(self):
        return u'Teacher:%s'%self.tname

3) 这里的 Course 类和 Teacher 类可以相互多选,是多对多的形式

6.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
为例

6.5 生成牵引文件

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

6.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

(补充:此时会在数据库里生成三张表 user_course 表、user_teacher 表和 user_teacher_cour 表,其中 user_teacher_cour 表是 user_course 表和 user_teacher 表的中间表)

6.7 查看导入到 MariaDB 数据库的表
6.7.1 进入 MariaDB 数据库

(django_env) [root@python mysite]# mysql -uroot -p

6.7.2 查看所有的库

MariaDB [(none)]> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| user               |
+--------------------+
4 rows in set (0.001 sec)

6.7.3 进入 user 库

MariaDB [(none)]> use user;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

6.7.4 查看 user 库里所有的表

MariaDB [user]> show tables;
+----------------------------+
| Tables_in_user             |
+----------------------------+
| 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             |
| user_course                |
| user_teacher               |
| user_teacher_cour          |
+----------------------------+
13 rows in set (0.001 sec)

(补充:这里的 user_teacher_cour 表是自动创建的,user_course 表和 user_teacher 表的中间表)

6.7.5 查看 user_course 表、user_teacher 表和 user_teacher_cour 表里的数据

MariaDB [user]> select * from user_course;
Empty set (0.001 sec)

MariaDB [user]> select * from user_teacher;
Empty set (0.001 sec)

MariaDB [user]> select * from user_teacher_cour;
Empty set (0.001 sec)

6.7.6 查看 user_course 表、user_teacher 表和 user_teacher_cour 的表结构

MariaDB [user]> desc user_course;
+-------------+-------------+------+-----+---------+----------------+
| Field       | Type        | Null | Key | Default | Extra          |
+-------------+-------------+------+-----+---------+----------------+
| course_no   | int(11)     | NO   | PRI | NULL    | auto_increment |
| course_name | varchar(30) | NO   |     | NULL    |                |
+-------------+-------------+------+-----+---------+----------------+
2 rows in set (0.004 sec)

MariaDB [user]> desc user_teacher;
+-------+-------------+------+-----+---------+----------------+
| Field | Type        | Null | Key | Default | Extra          |
+-------+-------------+------+-----+---------+----------------+
| tno   | int(11)     | NO   | PRI | NULL    | auto_increment |
| tname | varchar(30) | NO   |     | NULL    |                |
+-------+-------------+------+-----+---------+----------------+
2 rows in set (0.002 sec)

MariaDB [user]> desc user_teacher_cour;
+------------+------------+------+-----+---------+----------------+
| Field      | Type       | Null | Key | Default | Extra          |
+------------+------------+------+-----+---------+----------------+
| id         | bigint(20) | NO   | PRI | NULL    | auto_increment |
| teacher_id | int(11)    | NO   | MUL | NULL    |                |
| course_id  | int(11)    | NO   | MUL | NULL    |                |
+------------+------------+------+-----+---------+----------------+
3 rows in set (0.002 sec)

步骤七:测试 Django 一对多多表
7.1 配置 Django 环境
7.1.1 进入 Python 环境

(django_env) [root@python mysite]# python3

7.1.2 引入 os 模块和 django 模块

>>> import os,django

7.1.3 调用 mysite.settings 的配置

>>> os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings")
'mysite.settings'

7.1.4 让刚刚的调用生效

>>> django.setup()

7.1.5 调用 mysite 项目 user 应用 models 模块里的所有内容

>>> from user.models import *

7.2 插入多对多多表数据
7.2.1 往 Course 表插入三条数据(插入三条课程数据)

>>> cour1 = Course.objects.create(course_name='Python')
>>> cour2 = Course.objects.create(course_name='Shell')
>>> cour3 = Course.objects.create(course_name='HTML')

(补充:这里以随意插入三条数据为例)

7.2.2 往 Teacher 表插入两条数据(插入两条老师数据)

>>> t1 = Teacher.objects.create(tname='zhangsan')
>>> t2 = Teacher.objects.create(tname='lisi')

(补充:这里以随意插入两条数据为例)

7.2.3 让 Teacher 表里的某一条数据关联 Course 表中的三条数据

>>> t1.cour.add(cour1,cour2,cour3)

(补充:这里以让 t1 数据中的老师选择 cour1、cour2 和 cour3 数据里课程为例)

7.3 查看多对多多表数据
7.3.1 查看多对多多表数据的性质

1) 这里从 Course 表到 Teacher 表的查询正向查询
2) 这里从 Teacher 表到 Course 表的查询逆向查询

7.3.2 正向查询数据

>>> Course.objects.first().teacher_set.all()
<QuerySet [<Teacher: Teacher:zhangsan>]>


补充:
1) 集合后面需要添加 all(),如果不是集合只是对象则不需要添加 all()
2) 这里的 QuerySet 代表多对多
3) 这里的 _set 代表一对多,有一对多的就会有 _set

7.3.3 逆向查询数据

>>> Teacher.objects.first().cour.all()
<QuerySet [<Course: Course:Python>, <Course: Course:Shell>, <Course: Course:HTML>]>


补充:
1) 集合后面需要添加 all(),如果不是集合只是对象则不需要添加 all()
2) 这里的 QuerySet 代表多对多

7.4 使用对象插入一对多多表数据
7.4.1 创建一个插入数据的对象

>>> def insertData(tname,*coursenames):
...     try:
...         t = Teacher.objects.get(tname=tname)
...     except Teacher.DoesNotExist:
...         t = Teacher.objects.create(tname=tname)
...     courseList = []
...     for cn in coursenames:
...         try:
...             cou = Course.objects.get(course_name=cn)
...         except Course.DoesNotExist:
...             cou = Course.objects.create(course_name=cn)
...         courseList.append(cou)
...     t.cour.add(*courseList)
...


补充:
1) 这里的星号 “*” 代表一个可变参数
2) 一个星号 “*” 代表是一个元组的形势,各个元素单独存在且用逗号隔开
3) 两个星号 “**” 代表是一个键值对,用 = 的方式存在且用逗号隔开

7.4.2 使用对象插入多对多多表数据

>>> insertData('wangwu','SQLite','MySQL')


补充:结合 7.4.1 这里以
1) 在 Teacher 表中插入 wangwu 数据
2) 在 Course 表中插入 SQLite 数据和 MySQL 数据
3) wangwu 对应 SQLite 数据和 MySQL 数据
为例