0. 学城项目 后端环境配置

1. 企业的web项目类型

1. 商城 (某某团购)
	1.1 B2C直销商城 商家与会员直接交易(Busioness To Customer)
	1.2 B2B批发商城 商家与商家直接交易
	1.3 B2B2C购物平台 商家和会员在另一个商家提供的平台上进行交易
	1.4 C2B定制商城 会员向商家发起定制商品的需求, 商家去完成
	1.5 O2O线上线下交易平台
	1.6 C2C二手交易平台
2. 门户网站[企业网站和门户网站]
3. 社交网络 (APP后端) 
4. 咨询论坛 (技术, 买资料)
5. 内部系统 (办公管理, 人事管理, 客户关系管理)
6. 个人博客
7. 内容收费

2. 开发流程

2.1 项目来源
1. 公司需求
2. 客户定制
3. 互联网项目
2.2 流程

image-20220429230645162

* 1. 立项
     需求分析(产品经理, 技术人员) --> 产品原型 --> /后端
* 2. 前端(根据原型图)
     ui前端 --> ui切图 --> 前端实现 
* 3. 后端
     项目架构, 技术选型 --> 需求说明书, 原型图 --> 开发接口 --> 接口文档
* 4. 前后端代码整合
     前后端联调 --> 继承测试(测试部, 质量控制部...)
* 5. 上线

工作流程: 公司项目管理平台(禅道...) --> 看自己的任务 --> 确定需求(询问测试, 询问发布任务的人员) 
--> 写代码 --> 提交到git仓库 --> 管理平台将需求设置完成
2.3 开发模式
瀑布模式: 早期被广泛采用的软件开发模型 --> 开发完在测试 --> 出问题在调试
敏捷开发: 完成一个模块--> 测试 --> 上线 --> 下一个循环
  	     scrum --> Sprint周期(小功能从开发到完成的时间) -->1 
  	     不做整体数据库的设计 --> 写到哪个模块,再去设计相关表
2.4 路飞项目需求
1. 首页轮播图
2. 登陆注册
       多方式登陆,手机号登陆
       手机号注册
3.课程列表
  	   过滤,排序
4.课程详情
  	  视频播放,课程介绍
5.下单/支付
      支付宝支付
      回调修改订单

3. pip换源

直接通过pip访问的是外网, 速度慢. 将pip的访问地址换成国内的地址, 加快下载模块的速度.
国内一些机构对Python官网的模块进行了备份.

国内五大源:
    阿里云           http://mirrors.aliyun.com/pypi/simple/
    中国科技大学     https://pypi.mirrors.ustc.edu.cn/simple/
    豆瓣            http://pypi.douban.com/simple/
    清华大学        https://pypi.tuna.tsinghua.edu.cn/simple/
    中国科学技术大学  http://pypi.mirrors.ustc.edu.cn/simple/
3.1 临时修改
临时修改: pip install xxx -i 地址
pip install pymysql -i http://pypi.douban.com/simple

image-20220429234221769

3.2 永久修改
在计算机本地设置一个文件, 在下载模块的时候会依据这个文件的地址寻找模块进行下载.
* 1. 在路径栏中输入 %APPDATA% 到达 C:\Users\用户名\AppData\Roaming 的路径下
  AppData文件夹: 是有关帐户信息, 系统桌面, 安装文件记录, 快速启动文件夹等内容的.
  Roaming文件夹: 主要是用来存放一些程序运行后产生的数据文件.

image-20220429232805690

* 2. 新建pip文件夹

image-20220429233010718

* 3. 建立 pip.ini 配置文件

image-20220429233127520

* 4. 在配置文件中输入以下配置信息, 并保存!
[global]
index-url = http://pypi.douban.com/simple
[install]
use-mirrors = true
mirrors = http://pypi.douban.com/simple/
trusted-host = pypi.douban.com
3.3 Pycharm换源

2022-05-11_00602

2022-05-11_00603

4. 创建虚拟环境

同一个版本的Python建立的项目只能对应一个版本的模块.
    :
    项目1, python3.6 使用 django1.x (运行项目2之后运行项目1, 需要卸载django2.x, 重装django1.x)
    项目2, python3.6 使用 django2.x (运行项目1之后运行项目2, 需要卸载django1.x, 重装django2.x)
    在开发多个软件的时候, 使用的模块版本不同则需要重新下载安装.

使用虚拟环境的好处:
不同的应用, 开发环境相互独立, 环境升级不影响其他应用, 也不会影响全局的Python环境.
防止出现包管理混乱及包版本冲突.
4.1 常用命令
1. 创建项目
   命令: mkvirtualenv -p python3.8 虚拟环境名字  

2. 查看创建的虚拟环境
   命令: workon
   
3. 使用虚拟环境
   workon 虚拟环境名字  

4. 进入|退出 虚拟环境的Python环境
  python | exit()
  
5. 为虚拟环境安装模块(已经进入到虚拟环境中)
   pip install 模块名

6. 退出当前虚拟环境
   deactivate
   
7. 删除虚拟环境 (删除当前虚拟环境要先退出, 也可以直接找到项目文件夹删除)
   rmvirtualenv 虚拟环境名字  
4.2 虚拟环境下创建项目
* 1. 安装依赖的模块
pip install virtualenv  虚拟环境模块: 创建虚拟环境麻烦 搭配↓
pip install virtualenvwrapper-win  虚拟环境辅助模块: 更快捷方便的操作和管理虚拟环境
* 2. 建立项目存放目录
     在D盘下创建一个Virtualenvs文件夹
* 3. 配置环境变量
     变量名 WORKON_HOME
     变量值 D:\Virtualenvs

2022-04-30_00408

* 4. 指定virtualenvwrapper.bat脚本代码, 将配置信息同步
     找到安装Python的目录, 打开Script目录 以管理员身份运行virtualenvwrapper.bat文件
     执行一闪而过, 看不到什么信息的

image-20220429235814286

* 5. 在D:\Virtualenvs中使用命令提示符创建虚拟环境项目
     命令: mkvirtualenv -p python3.8 虚拟环境名称
     查看创建的虚拟环境
     命令: workon
D:\Virtualenvs>mkvirtualenv -p python3.8 luffy
执行之后命令提示符中出现(项目名)

image-20220430001503325

* 7. 查看虚拟环境的文件 

image-20220430002713303

lib目录下放  安装的模块包.
Script目录下放 Python解释器, pip安装包管理工具.
* 8. 进入虚拟环境
	 命令: workon luffy
* 9. 安装Django(以后PyCharm中需要依赖虚拟环境直接创建Django项目, 就在虚拟环境中先安装好)
     命令: pip install django==2.2.14

image-20220513135650057

4.3 Pycharm使用虚拟环境
* 1. 创建项目时选择虚拟环境中的python.exe
     不需要创建模板  app

image-20220513220902853

Note注意提示 Python下载的包会安装到选中的解释器中.

image-20220511211207401

templates 目录可以不创建. 创建了后续删除即可, 使用的是Django2.2.14 需要修改templates的配置文件
TEMPLATES = [
    {
        'DIRS': [BASE_DIR, 'templates']  # 修改文件拼接符号
        ...

5. 重构项目目录

luffy                  项目名  
  |--logs/             项目运行事/开发时 的日志目录 -包
  |--script/           项目临时使用脚本文件目录
  |--doc/              存放项目介绍信息
      |--readme.md     项目说明
  |--luffy/            项目主应用, 开发时代码存放的目录 -包
      |--urls.py       总路由文件
      |--wsgi.py       Web服务器网关接口
      |--utils/        多个模块, 子应用的公共函数类库, 自己开发的组件
      |--apps/         开发者的代码存放的目录, 以子应用为目录 -包
      |--libs/         第三类/库存放目录, 第三方组件, 模块, 
      |--settings/     配置目录
         |--dve.py     项目来发是本地配置文件
         |--prod.py    项目上线是运行的配置文件
 |--requirement.txt    项目依赖的模块
* 1. 现在项目文件下新建
     doc 文件夹 --> readme.md 项目介绍文件
     logs 文件夹
     scripr 

2022-05-13_00648

* 2. 在项目名文件夹中创建
     apps 文件夹
     utils 文件夹
     settings 文件夹 
     将项目名文件夹下的settings.py 复制两份 到settings文件夹中, 分别命令为dev.py  prod.py
     原来settings.py 文件删除.

image-20220513140453205

修改配置文件的位置之后, manage.py 控制台文件会找不到, 直接运行会报错!
django.core.exceptions.ImproperlyConfigured: The SECRET_KEY setting must not be empty.
* 3. 修改控制台文件manage.py
     直接使用settings/dve.py的配置文件, 在配置中.文件名即可, 不需要后缀
     os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'luffy.settings.dev')

2022-04-30_00418

* 4. 启动按钮重新配置(不修会出问题)
	也会报错
	django.core.exceptions.ImproperlyConfigured: The SECRET_KEY setting must not be empty.
	修改为:
     PYTHONUNBUFFERED=1; DJANGO_SETTINGS_MODULE=luffy.settings.dev

image-20220430015202774

* 5. 启动项目, 启动项目之后会生成sqlite3的数据库文件, 不需要可以删除!

image-20220430014719591

* 6. 上面配置文件需要在wsgi.py文件中配置(上线前就所有的配置信息使用的dev的, 上线的时候去复制一份
不用每次配置文件都修改两个文件)

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'luffy.settings.prod')

image-20220430015351536

* 7. 国际化设置(在两个配置文件中设置)
LANGUAGE_CODE = 'zh-hans'

TIME_ZONE = 'Asia/shanghai'

USE_I18N = True

USE_L10N = True

USE_TZ = False
* 8. 创建app, 需要在apps包的路径下执行 python manage.py startapp app应用
	 该命令在哪里执行则会在那创建app. (下面的apps名字搞错了全部因该是home 写user习惯了)
1. 先切换路径到apps目录中
    PS F:\synchro\Project\luffy> cd luffy/apps
2. 执行创建app命令
    PS F:\synchro\Project\luffy\luffy\apps> python ../../manage.py startapp user

image-20220430021049058

* 8. 配置文件中将 BASE_DIR  apps的路径添加到环境变量中
     设置环境变量之后可以直接导入模块(2.2.14使用的Path模块拼接路径)
import os
import sys

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, BASE_DIR)
sys.path.insert(1, os.path.join(BASE_DIR, 'apps'))

"""
BASE_DIR是配置文件的上一级上一个文件夹 项目名文件夹.
将项目名文件夹与 其子目录apps 添加到环境变量中.
"""

2022-04-30_00425

环境变量的使用场景
在导入文件的时候, 导入路径越短越好, 
如果导入的路径中经过py文件会执行该文件, 路径过长可能会出问题(循环导入...)
在py文件中使用绝对路径与相对路径 ... 导入模块的后, 该文件只能直接运行, 只能够被其他的文件调用.

2022-04-30_00426

 项目名文件夹  apps设置 Sources Root

2022-04-30_00427

之后则不会飘红了, 这个东西不能乱设置, 必须确保这个路径在环境变量中找到!

image-20220430024151444

* 9. 注册app, 配置文件与app文件都改变了, 但是将apps添加环境变量中后, 便能够直接注册app.
     sys.path.insert(1, os.path.join(BASE_DIR, 'apps')) 设置的作用.
# app应用列表
INSTALLED_APPS = [
	...
    'user',  # 将apps添加到环境变量之后, 导入应用是能够直接找到user app
]

6. 数据库配置

6.1 创建数据库
* 1. 在cmd中使用管理员连接数据库
     命令: mysql -uroot -p123
C:\Users\13600>mysql -uroot -p123
* 2. 创建数据库
     命令: create databse luffy default charset=utf8;
mysql> create database luffy default charset=utf8;
Query OK, 1 row affected (0.02 sec)
* 3. 查看创建的数据库
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| luffy              |
| performance_schema |
+--------------------+
3 rows in set (0.01 sec)
* 4. 查看用户信息
     命令: select user, host, password from mysql.user;
     5.7之后版本: select user, host, authentication_string from mysql.user;
mysql> select user, host, password from mysql.user;
+------+-----------+-------------------------------------------+
| user | host      | password                                  |
+------+-----------+-------------------------------------------+
| root | localhost | *23AE809DDACAF96AF0FD78ED04B6A265E05AA257 |
| root | 127.0.0.1 |                                           |
| root | ::1       |                                           |
|      | localhost |                                           |
+------+-----------+-------------------------------------------+
4 rows in set (0.00 sec)
6.2 为数据库指定用户
在打开项目的时候不直接使用root用户去连接数据库, 而是创建一个用户去操作数据表.
使用root用户登入之后, 新建一个用户, 并为用户设置权限, 密码
授权账户名: grant 权限(create, update...) on . to '账户'@'host' identified by '密码'
* 1. 配置任意ip都可以连接数据的账户
命令: grant all privileges on luffy.* to 'luffy'@'%' identified by 'Luffy123?';
mysql>  grant all privileges on luffy.* to 'luffy'@'%' identified by 'Luffy123?';
Query OK, 0 rows affected (0.00 sec)
* 2. 由于数据库版本问题, 可能本地连接不上, 为本地用户单独配置
C:\Users\13600>mysql -uluffy -pLuffy123?
Warning: Using a password on the command line interface can be insecure.
ERROR 1045 (28000): Access denied for user 'luffy'@'localhost' (using password: YES)
mysql>  grant all privileges on luffy.* to 'luffy'@'localhost' identified by 'Luffy123?';
Query OK, 0 rows affected (0.02 sec)
* 3. 重新加载权限
     命令: flush privileges;
* 4. 查看用户信息
     只能操作数据的账户 luffy 密码 Luffy123?
mysql> select user, host, password from mysql.user;
+-------+-----------+-------------------------------------------+
| user  | host      | password                                  |
+-------+-----------+-------------------------------------------+
| root  | localhost | *23AE809DDACAF96AF0FD78ED04B6A265E05AA257 |
| root  | 127.0.0.1 |                                           |
| root  | ::1       |                                           |
| luffy | %         | *A5576062BB7EC62806008F537658C42F0456DB9B |
| luffy | localhost | *A5576062BB7EC62806008F537658C42F0456DB9B |
+-------+-----------+-------------------------------------------+
5 rows in set (0.00 sec)
* 5. 登入
C:\Users\13600>mysql -uluffy -pLuffy123?
...
>mysql
* 6. PyCharm中下载pymysql
     pip install pymysql

image-20220430134426626

* 7. 配置文件中设置连接数据库的信息
# 数据配置属性
DATABASES = {
    'default': {
        # 修改连接数据库的引擎
        'ENGINE': 'django.db.backends.mysql',
        # 连接的数据库
        'NAME': 'luffy',
        # 使用的账户
        'USER': 'luffy',
        # 账户的密码
        'PASSWORD': 'Luffy123?',
        # 地址, 本地 127.0.0.1 或 localhost
        'HOST': '127.0.0.1',
        # 端口
        'POST': 3306
    }
}

# 执行替换数据库操作(直接在配置文件中设置即可)
import pymysql
pymysql.install_as_MySQLdb()
* 8. Django 2.0.7 版本后可以出现一些问题, 需要修改源码

2022-04-30_00431

* 9. 如果提示 需要mysqlclient 1.3.13或更新版本, 去pymysql的源代码中 将版本提示代码注释掉
# if version < (1, 3, 13):
#     raise ImproperlyConfigured('mysqlclient 1.3.13 or newer is required; you have %s.' % Database.__version__)

2022-04-30_00432

7. 创建User表

用户表基于内置auth的user表.
注意: 在继承该表之前执行过数据库迁移命令, 后期想继承该表, 需要把所有app下的迁移文件删除, 之后删除库中表.
1. 删除 admin, auth, 自定义的app下的migrate文件的迁移文件, __init__.py 不能删除!
2. 删库使用Navicat Premium 将数据库的文件保存好, 再删除表文件重新执行数据库迁移命令!

* 7.1用于演示可以跳过到7.2
7.1 创建表之后继承用户
from django.contrib import admin
from django.contrib import auth

2022-04-30_00434

* 1. 创建用户表, 先不继承AbstractUser (测试)
from django.db import models

class User(models.Model):
    # 拓展手机号
    phone = models.CharField(max_length=11, verbose_name='手机号码')
    # 拓展头像 设置头像上传地址, 默认头像
    icon = models.ImageField(upload_to='icon', default='icon/default.png')
* 2. 配置文件中, 设置媒体文件路径
# 媒体文件设置
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
* 3. 在项目目录下创建media/icon目录, 添加一个默认头像, 文件名default.png

image-20220430180900293

* 4. 开发媒体文件的访问
from django.contrib import admin
from django.urls import path, re_path
# 导入serve视图类
from django.views.static import serve
# 导入内置配置文件, 会自动到dev.py配置文件中去查询
from django.conf import settings
urlpatterns = [
    path('admin/', admin.site.urls),
    re_path('media/(?P<path>.*)', serve, {'document_root': settings.MEDIA_ROOT})
]
* 5. 头像上传依赖Pillow模块
pip install Pillow
* 6. 执行数据库迁移命令
python manage.py makemigrations
python manage.py migrate   
* 7. 在继承AbstractUser
from django.db import models

# Create your models here.
from django.contrib.auth.models import AbstractUser


class User(AbstractUser):
    # 拓展手机号
    phone = models.CharField(max_length=11, verbose_name='手机号码')
    # 拓展头像 设置头像上传地址, 默认头像
    icon = models.ImageField(upload_to='icon', default='icon/default.png')
* 8. 配置使用自己定义的user表
# 'app.表名'
AUTH_USER_MODEL = 'user.user'
* 9. 执行数据库迁移命令
PS F:\synchro\Project\luffy> python manage.py makemigrations
You are trying to add a non-nullable field 'password' to user without a default; we can't do that (the database needs something to populate existing rows).
Please select a fix:
 1) Provide a one-off default now (will be set on all existing rows with a null value for this column)
 2) Quit, and let me add a default in models.py
Select an option:


您正在尝试向用户添加一个不可为空的字段“password”,而没有默认值;我们不能这样做(数据库需要一些东西来填充现有的行)。
请选择修复程序:
1 现在提供一个一次性默认值(将在所有现有行上设置此列的空值)
2 退出,让我在模型中添加一个默认值
* 10. 删除数据库迁移文件

2022-04-30_00435

admin  auth 的数据库迁移文件第一次右击选择删除后, 文件还存在, 倒是右击没有了删除选项, 则代表删除成功!

2022-04-30_00436

2022-04-30_00437

* 11. 删除所有已经创建的表
使用Navicat Premium 连接数据库, 先点测试连接, 测试成功点击确定.
库名 luffy
用户 luffy
密码 Luffy123?

image-20220430175423864

一次无法全部删除, 剩下的表在全选中删除即可

image-20220430175520499

* 12. 执行数据库迁移命令
python manage.py makemigrations
python manage.py migrate   
* 13. 启动项目, 测试媒体文件的访问
http://127.0.0.1:8000/media/icon/default.png

7.2 直接继承内置用户表
* 1. 继承内置用户表
from django.db import models

# Create your models here.
# 导入内置用户表
from django.contrib.auth.models import AbstractUser


# 定义用户表
class User(AbstractUser):
    # 拓展手机号
    phone = models.CharField(max_length=11, verbose_name='手机号码')
    # 拓展头像 设置头像上传地址, 默认头像
    icon = models.ImageField(upload_to='icon', default='icon/default.png')
* 2. 在dev配置文件中配置使用自己定义的user表
# 'app.表名'
AUTH_USER_MODEL = 'user.user'
* 3. dev配置文件中, 设置媒体文件路径
# 媒体文件的配置
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
* 4. 在项目名目录下创建media/icon目录, 添加一个默认头像, 文件名default.png

image-20220430180900293

* 5. 开放媒体文件的访问(admin没有创建, 将admin的代码注释掉)
# 项目名文件夹下的urls.py
from django.contrib import admin
from django.urls import path, re_path
# 导入serve视图类
from django.views.static import serve
# 导入内置配置文件, 会自动到dev.py配置文件中去查询
from django.conf import settings
urlpatterns = [
    path('admin/', admin.site.urls),
    re_path('^media/(?P<path>.*)', serve, {'document_root': settings.MEDIA_ROOT})
]
* 6. 头像上传依赖Pillow模块
    pip install Pillow
* 7. 执行数据库迁移命令
python manage.py makemigrations
python manage.py migrate   
* 8. 启动项目, 测试媒体文件的访问
     172.0.0.1:8000/media/icon/default.png

8. xadmin管理后台

* 1. 创建超级用户用于登入后端管理
     python manage.py createsuperuser
     用户名: root
     密码: zxc123456

image-20220513121600301

* 2. 下载xadmin模块
	 pip install https://codeload.github.com/sshwsfc/xadmin/zip/django2(下载最新的不要用)
	 去github找到适用于django2.x版本的xadmin

image-20220513163812120

解压后里面有个xadmin就是我们需要的xadmin源码了, 将xadmin复制到apps中.(就是一个写好的app应用)

2022-05-13_00661

在解压后的目录中找到requirements.txt 这个文件中记录了xadmin需要使用的模块
django-crispy-forms>=1.6.0
django-import-export>=0.5.1
django-reversion>=2.0.0
django-formtools==2.1
future==0.15.2
httplib2==0.9.2
six==1.10.0
django==2.2.14 (修为当前使用的django版本, 不然Django会升级到最新的版本)

image-20220513190542328

将这个文件复制到项目目录下, 点击右上角的提示 install plugins 则会将文件中的模样依次下载.
也可以手动一个个的 pip install xxx模块==版本 安装
* 3. 在dev.py配置文件的中注册app
# xadmin主体模块
'xadmin',
# 渲染表格模块
'crispy_forms',
# 为模型通过版本控制,可以回滚数据
'reversion',
* 4. 数据迁移
python manage.py makemigrations
python manage.py migrate
执行数据迁移的时候会报错.
1. 注释掉下面的命令

from import_export.admin import DEFAULT_FORMATS, SKIP_ADMIN_LOG, TMP_STORAGE_CLASS
2. 增加下面两条

from import_export.formats.base_formats import DEFAULT_FORMATS
from import_export.admin import ImportMixin, ImportExportMixinBase

image-20220513185743673

* 5. 在dev配置文件中将xadmin的路径添加到环境变量中
sys.path.insert(2, os.path.join(BASE_DIR, 'apps/xadmin'))

image-20220513230515834

执行之后再重新执行数据迁移命令
* 6. 修改主路由
     将xadmin设置为Sources Root 不然会飘红
# 项目名文件夹下的urls.py
from django.contrib import admin
from django.urls import path, re_path, include
# 导入serve视图类
from django.views.static import serve
# 导入内置配置文件, 会自动到dev.py配置文件中去查询
from django.conf import settings

# xadmin的依赖
import xadmin

xadmin.autodiscover()
# xversion模块自动注册需要版本控制的 Model
from xadmin.plugins import xversion

xversion.register_models()

urlpatterns = [
    # 修改为访问的页面为xadmin的页面
    re_path('^xadmin/', xadmin.site.urls),
    re_path('^media/(?P<path>.*)', serve, {'document_root': settings.MEDIA_ROOT}),
    # 路由分发到user app
    re_path('user', include('user.urls'))
]
* 7. 登入后台

image-20220513230638383

* 8. 输入账户密码进入到后台

image-20220513230715983

* 9. user app目录下admin.py 
# user/adminx.py
# xadmin全局配置
import xadmin
from xadmin import views

class GlobalSettings(object):
    """xadmin的全局配置"""
    site_title = "路飞学城"  # 设置站点标题
    site_footer = "路飞学城有限公司"  # 设置站点的页脚
    menu_style = "accordion"  # 设置菜单折叠

xadmin.site.register(views.CommAdminView, GlobalSettings)

image-20220513234530303

8. 项目依赖库文件

软件开发目录规范中会有一个requirement.txt 文件, 该文件中存放项目依赖的模块.
pip list   查看所有的模块及版本号
pip freeze 查看所有的模块及版本号
8.1 导出模块信息
* 1. 查询模块及版本并追加到文件中, 在完成项目之后再执行即可.
pip freeze > requirement.txt

image-20220513230919065

8.2 依据文件下载模块
在拿到一个项目的时候, 只有项目的代码, 项目的模块不没有的.
开发者将模块信息写入到requirement.txt文件中, 那么根据这个文件则可以通过
pip install -r requirement.txt -i 豆瓣源 下载安装模块
8.3 whl模块文件安装
某些模块通过 pip install 命令可能安装不了, 可以将模块文件下载到本地再安装.
(windows装的模块, 都是 xxx.whl文件)
模块下载网站: https://www.lfd.uci.edu/~gohlke/pythonlibs/#twisted

image-20220430230253312

选择一个模块下载练习安装 cp python的版本

2022-04-30_00470

pip install 路径

image-20220430231149901

离线下载命令: 
pip download -r 模块名 -d '路径' 
pip download -r 模块名==1.1 -d '路径' 
pip download -r requirement.txt -d '路径' 

9. 全局异常配置&日志记录

9.1 自定义Response对象
统一异常信息的返回格式.
* 1. 安装rest_framework模块
     pip install djangorestframework==3.10.3

image-20220512142134190

* 2. 将rest_framework模块注册到app应用列表中
# app应用列表
INSTALLED_APPS = [
	...
    'rest_framework'
]
* 3. 在utils.py文件下创建 api_response.py 响应模块
# 1. 继承rest_framework的Response响应模块, 自定义响应格式.
from rest_framework.response import Response


class ResponseDataFormat(Response):
    # 初始化 (展示的状态码, 信息, 数据, 状态码
    def __init__(self, code=200, msg='访问成功!', data=None, status=None,
                 template_name=None, headers=None, content_type=None, **kwargs):
        # 定义一个字典
        dic = {'code': code, 'msg': msg}

        # data属性有值则将值条件到字典中
        if data:
            dic.update({'data': data})

        # 如果有而外的参数如, token, 也将值添加到字典中 kwargs是一个字典类型的值, 没有值是{}, 更新不影响
        dic.update(kwargs)

        # 调用Response的__init__生成Response对象并初始化值, super()==> Response对象, 对象调用方法将自己作为第一个参数进行传递
        super().__init__(data=dic, status=status,
                         template_name=template_name, headers=headers, content_type=content_type)
9.2 定义异常返回格式
* 1. 定义全局异常信息返回格式
     调用内置exception_handler异常处理模块处理三大认证的异常.
     调用自定义Response对象ResponseDataFormat统一返回的数据格式.
# 2. 定义全局异常信息返回格式
from rest_framework.views import exception_handler


def exception_response(exc, context):
    # 调用内置的异常处理模块, 接收返回值
    response = exception_handler(exc, context)

    # 判断返回的数据是否被内部的异常模块处理过(没有处理过返回None, 处理过返回的是一个response对象, 错误提示data属性中)
    if response:
        data = response.date.get('detail')
    else:
        data = str(exc)

    # 可以通过isinstance(exc, 错误类型) 对异常进行细分, 就不细分了, exc是一个错误类型的子对象


    return ResponseDataFormat(code=400, msg='访问失败', data=data)
* 2. 在dev.py配置文件中配置全局使用的异常处理模块
# 配置全局使用的异常处理程序
REST_FRAMEWORK = {
    'EXCEPTION_HANDLER': 'luffy.utils.api_response.exception_response'
}
9.3 日志配置
* 1. 在dev.py中添加日志模块的配置字典(Django官网提供的)
	 logs目录下会自动创建luffy.log 文件
# 字典, 日志的配置信息
LOGGING = {
    # 版本
    'version': 1,
    # 禁用现有的记录器
    'disable_existing_loggers': False,
    # 日志的格式(定义两个不同的格式)
    'formatters': {
        # 详细的版本
        'verbose': {
            'format': '%(levelname)s %(asctime)s %(module)s %(lineno)d %(message)s'
        },
        # 简单的版本
        'simple': {
            'format': '%(levelname)s %(module)s %(lineno)d %(message)s'
        },
    },
    # 过滤日志
    'filters': {
        'require_debug_true': {
            '()': 'django.utils.log.RequireDebugTrue',
        },
    },
    # 显示
    'handlers': {
        # 打印到终端的日志
        'console': {
            # 实际开发建议使用WARNING
            'level': 'DEBUG',  # 级别
            'filters': ['require_debug_true'],
            'class': 'logging.StreamHandler',
            'formatter': 'simple'  # 使用的格式
        },
        # 写入到文件
        'file': {
            # 实际开发建议使用ERROR
            'level': 'ERROR',  # 级别
            'class': 'logging.handlers.RotatingFileHandler',
            # 日志位置, 日志文件名, 日志保存目录必须手动创建, 注:BASE_DIR是项目名目录
            'filename': os.path.join(os.path.dirname(BASE_DIR), "logs", "luffy.log"),
            # 日志文件的最大值,这里我们设置300M
            'maxBytes': 300 * 1024 * 1024,
            # 日志文件的数量,设置最大日志数量为10
            'backupCount': 10,
            # 日志格式:详细格式
            'formatter': 'verbose',
            # 文件内容编码
            'encoding': 'utf-8'
        },
    },
    # 日志对象
    'loggers': {
        'django': {
            # 将日志打印到终端 并 写入到文件
            'handlers': ['console', 'file'],
            'propagate': True,  # 是否让日志信息继续冒泡给其他的日志处理系统
        },
    }
}
* 2. 在utils.py 新建logger.py模块, 模块中生成日志对象, 方便以后的调用.
# 导入logging模块
import logging
# 模块通过getLogger方法拿到配置文件中日志配置字段的loggers的django配置, 生成一个logging对象
log = logging.getLogger('django')
* 3. 在异常响应中记录日志
# 2. 定义全局异常信息返回格式
# 导入内置的异常处理模块
from rest_framework.views import exception_handler
# 导入日志对象
from .logger import log


def exception_response(exc, context):
    # 调用内置的异常处理模块, 接收返回值
    response = exception_handler(exc, context)

    # 判断返回的数据是否被内部的异常模块处理过(没有处理过返回None, 处理过返回的是一个response对象, 错误提示data属性中)
    if response:
        data = response.date.get('detail')
    else:
        data = str(exc)

    # 可以通过isinstance(exc, 错误类型) 对异常进行细分, 就不细分了, exc是一个错误类型的子对象

    # 组织日志格式
    # context["view"]拿到的当前的视图对象, 视图对象__class__ 拿到视图类类 视图类.__name__ 拿到视图类名称
    view = context["view"].__class__.__name__

    log_format = (f'当前视图: {view}, 报错信息: {data}.')
    # 记录日志
    log.error(log_format)
    return ResponseDataFormat(code=400, msg='访问失败', data=data)
9.4 测试
写一个视图类对全局异常日志代码进行测试.
* 1. 在项目名目录下的urls.py总路由文件中设置路由分发
# 项目名文件夹下的urls.py
from django.contrib import admin
from django.urls import path, re_path, include
# 导入serve视图类
from django.views.static import serve
# 导入内置配置文件, 会自动到dev.py配置文件中去查询
from django.conf import settings

# 导入xadmin
import xadmin
urlpatterns = [
    # 修改为访问的页面为xadmin的页面
    re_path('^xadmin/', xadmin.site.urls),
    re_path('^media/(?P<path>.*)', serve, {'document_root': settings.MEDIA_ROOT}),
    # 路由分发到user app
    re_path('user', include('user.urls'))
]
* 2. 在user目录下新建urls.py 子路由文件
from django.urls import re_path
# 导入视图类
from user import views

urlpatterns = [
    # 1. 异常&日志测试路由
    re_path('exception_log/', views.ExceptionLog.as_view())
]
* 3. 在apps目录下的views.py 视图层中写测试的视图类
# 1. 异常&日志测试
from rest_framework.views import APIView
from luffy.utils.api_response import ResponseDataFormat


class ExceptionLog(APIView):
    def get(self, request):
        return ResponseDataFormat(data='异常&日志测试!')
* 4. 启动程序正常访问 (三大认证与视图类中现在是没有任何错误的)
     127.0.0.1:8000/user/exception_log/
     # csnd你牛逼在前上面这个链接加了http, 就提示文章质量低!!!

image-20220512174727082

* 5. 查看日志文件信息

2022-05-12_00613

* 6. 在视图类中手写bug. 测试视图类出现异常记录日志.
# 1. 异常&日志测试
from rest_framework.views import APIView
from luffy.utils.api_response import ResponseDataFormat


class ExceptionLog(APIView):
    def get(self, request):
        print(xxx)  # 这里加bug
        return ResponseDataFormat(data='异常&日志测试!')
* 7. 启动程序, 访问 http://127.0.0.1:8000/user/exception_log/

image-20220512175255639

* 8. 查看日志与窗口的日志信息

2022-05-12_00615

* 9. 测试成功, 将手写的bug删除!
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值