后台日志封装、封装全局异常、二次封装response、路飞数据库配置、软件开发模式、User模块用户表、django的配置文件讲解、开启media访问

一、后台日志封装(logger)

以后,项目肯定要记录日志

-日志都可以打印到控制台
-日志可以写到日志文件中
-日志存到某个库中
-所有项目日志统一管理 sentry:django写的服务,搜集日志的,可以展开 开源的

使用日志之后,在项目中不要出现print了,以后都用日志logger.info()打印信息,以后项目上线,只需要调整日志级别,低级别的日志就不打印了,于是日志输出不用删掉

操作步骤

django中集成日志步骤,django使用的就是python内置的日志模块

  • 第一步:复制代码(之前学过的日志字典)到配置文件中(dev.py)

    代码如下:

    点击查看代码
    # 真实项目上线后,日志文件打印级别不能过低,因为一次日志记录就是一次文件io操作
    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配置的是输出到控制台中的日志内容
    'console': {
    # 实际开发建议使用WARNING
    'level': 'WARNING',
    'filters': ['require_debug_true'],
    'class': 'logging.StreamHandler',
    'formatter': 'simple'
    },
    # file配置的是记录到日志文件中的日志内容
    'file': {
    # 实际开发建议使用ERROR
    'level': 'ERROR',
    'class': 'logging.handlers.RotatingFileHandler',
    # 日志位置,日志文件名,日志保存目录必须手动创建,注:这里的文件路径要注意BASE_DIR代表的是小luffyapi
    '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, # 是否让日志信息继续冒泡给其他的日志处理系统
    },
    }
    }
  • 第二步:在utils新建 common_logger.py ,写入下方代码,得到日志对象

    import logging
    # 通过配置问中的名字拿到logger对象,以后只需要导入,直接使用对象写日志即可
    logger=logging.getLogger('django')
  • 第三步:在任意想用日志的地方,导入使用即可

    views.py

    from utils.common_logger import logger
    from django.http import JsonResponse
    def test_logger(request):
    logger.info('info级别的日志')
    logger.error('error级别的日志')
    return JsonResponse({'name':'zzh'})

    urls.py

    from django.contrib import admin
    from django.urls import path
    from user import views
    urlpatterns = [
    path('admin/', admin.site.urls),
    path('test_logger/', views.test_logger),
    ]

    ppCnIG4.png

二、封装全局异常

前端要接收的格式要统一,无论后端是否出错

在drf的三大认证,视图类的方法中只要出了异常,就会执行一个函数,但是这个函数只能出了drf的异常

因此我们需要自己写个函数,既能处理drf异常,又能处理django异常,止痒前端看到的格式都统一了

127.0.0.1和0.0.0.0路由在项目中的区别

当我们在访问项目的路由时,如果使用的是127.0.0.1的本地路由,只有我们自己的计算机可以访问项目的路由

当我们使用0.0.0.0充当路由时,同一个局域网内的所有计算机都能访问我们项目的路由

使用步骤

因为我们要用到drf,所以需要安装Djangorestframework模块

第一步:在utils中新建common_exceptions.py

第二步:在common_exceptions.py中编写全局异常处理函数

from rest_framework.views import exception_handler as drf_exception_handle
from rest_framework.response import Response
from utils.common_logger import logger
def exception_handler(exc, context):
# 程序出了异常,会走到这,我们都要记录日志
# 请求地址,请求方式,请求时间,请求哪个视图函数,如果登录了,记录一下用户id
request = context.get('request')
try:
user_id = request.user.pk
if not user_id:
user_id = '匿名用户'
except:
user_id = '匿名用户'
view = context.get('view')
logger.error('用户:【%s】,使用:【%s】 请求,请求:【%s】 地址,视图函数是:【%s】,出错了,错误是:【%s】' % (
user_id, request.method, request.get_full_path(), str(view), str(exc)
))
# 第一步:执行一下原来的异常处理:它只处理drf的异常,django的异常没有处理
# res如果有值是Response的对象,说明是drf的异常
# res如果是None,说明是django的异常
res = drf_exception_handle(exc, context)
# 在这里,可以通过状态码,把异常分的更细一些:比如有数据的异常,除以0的异常,列表越界异常。。。。
if res:
# drf异常
# res=Response(data={'code':999,'msg':'服务器出错,请联系系统管理员'})
res = Response(data={'code': 999, 'msg': res.data.get('detail', '服务器出错,请联系系统管理员')})
else:
# django的异常,状态码是888,错误信息是 exc异常对象转成字符串
res = Response(data={'code': 888, 'msg': str(exc)})
return res
# 在配置文件中配置

ps:这里因为需要用warning级别的日志记录drf中的错误,所以需要修改配置文件中的日志记录等级

点击查看代码
# 真实项目上线后,日志文件打印级别不能过低,因为一次日志记录就是一次文件io操作
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配置的是输出到控制台中的日志内容
'console': {
# 实际开发建议使用WARNING
'level': 'WARNING',
'filters': ['require_debug_true'],
'class': 'logging.StreamHandler',
'formatter': 'simple'
},
# file配置的是记录到日志文件中的日志内容
'file': {
# 实际开发建议使用ERROR
'level': 'WARNING',
'class': 'logging.handlers.RotatingFileHandler',
# 日志位置,日志文件名,日志保存目录必须手动创建,注:这里的文件路径要注意BASE_DIR代表的是小luffyapi
'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, # 是否让日志信息继续冒泡给其他的日志处理系统
},
}
}

第三步:在配置文件中注册drf的app,并修改drf使用的异常处理函数以后只要出了异常,都会走咱们的函数

INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'home',
'user',
]
# drf的配置
REST_FRAMEWORK = {
'EXCEPTION_HANDLER': 'utils.common_exceptions.exception_handler',
}

第四步:在视图层中测试

views.py

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.exceptions import APIException
class TestExcepiton(APIView):
def get(self, request):
# drf 异常
raise APIException('drf抛出异常')
# 未知错误
# l = [1, 23, 4]
# print(l[9])
# 9/0
# django主动抛的错误
# raise Exception('出错了')
return Response('ok')

urls.py

from django.contrib import admin
from django.urls import path
from user import views
urlpatterns = [
path('admin/', admin.site.urls),
path('test_logger/', views.test_logger),
path('test_exception/', views.TestExcepiton.as_view()),
]

ppC1SKJ.png

ppC1iUx.png

当我们配置好全局异常处理后,就可以勇敢大胆写代码,即便报错,程序不会蹦,并且会记录日志,并且处理成统一格式

如果我们在配置了全局异常处理的情况下出现程序报错停止的情况,就说明我们编写的全局异常处理函数(common_exceptions.py)中出了问题

三、二次封装response

如果我们在配置了全局异常处理的情况下出现程序报错停止的情况,就说明我们编写的全局异常处理函数(common_exceptions.py)中出了问题

因此我们自己封装一个Response类,以后都用我们自己封装的,方便咱们写code和msg

{code:100,msg:提示,data:{}/[]}
{code:100,msg:提示,token:dasdasda,user:xxx}

封装之后的效果:code,msg可以不传,不传就用默认的值

配置步骤

  • 第一步:在utils下新建common_response.py

  • 第二步:在common_response.py中封装APIRseponse

    这里使用了字典的update方法,基本作用就是更新有的字段,并且把没有的字段添加进去

    from rest_framework.response import Response
    '''
    以后使用
    -return APIResponse()----------前端收到-->{code:100,msg:成功}
    -return APIResponse(token=xsdse,username=lqz)----------前端收到-->{code:100,msg:成功,token:xsdse,username:lqz}
    -return APIResponse(data=[{},{},{}])----------前端收到-->{code:100,msg:成功,data:[{},{},{}]}
    -return APIResponse(code=101,msg=失败)----------前端收到-->{code:101,msg:失败}
    -return APIResponse(headers={'xx':'xx'})----------前端收到-->{code:100,msg:成功},但是响应头中有xx=xx
    -return APIResponse(status=201)----------前端收到-->{code:100,msg:成功},但是响应状态码是201
    '''
    class APIResponse(Response):
    def __init__(self, code=100, msg='成功', status=None, headers=None, **kwargs):
    data = {'code': code, 'msg': msg}
    if kwargs: # 有值,说明传了,除了code msg status headers 以外的,咱们都要返回给前端,放到这个data中
    data.update(kwargs)
    # Response(data=data, status, headers=headers)
    super().__init__(data=data, status=status, headers=headers)
    # 不要return,你可以这样做 self.data=data self.status=status
  • 第三步:导入使用,视图函数的方法,返回时,都使用咱们自己的

    views.py

    from rest_framework.response import Response
    '''
    以后使用
    -return APIResponse()----------前端收到-->{code:100,msg:成功}
    -return APIResponse(token=xsdse,username=lqz)----------前端收到-->{code:100,msg:成功,token:xsdse,username:lqz}
    -return APIResponse(data=[{},{},{}])----------前端收到-->{code:100,msg:成功,data:[{},{},{}]}
    -return APIResponse(code=101,msg=失败)----------前端收到-->{code:101,msg:失败}
    -return APIResponse(headers={'xx':'xx'})----------前端收到-->{code:100,msg:成功},但是响应头中有xx=xx
    -return APIResponse(status=201)----------前端收到-->{code:100,msg:成功},但是响应状态码是201
    '''
    class APIResponse(Response):
    def __init__(self, code=100, msg='成功', status=None, headers=None, **kwargs):
    data = {'code': code, 'msg': msg}
    if kwargs: # 有值,说明传了,除了code msg status headers 以外的,咱们都要返回给前端,放到这个data中
    data.update(kwargs)
    # Response(data=data, status, headers=headers)
    super().__init__(data=data, status=status, headers=headers)
    # 不要return,你可以这样做 self.data=data self.status=status

    urls.py

    from django.urls import path
    from user import views
    urlpatterns = [
    path('test_apiresponse/', views.TestAPIResponse.as_view()),
    ]

    ppPSqvF.png

四、luffy数据库创建

1、创建用户创建库

  • 创建luffy数据库使用mysql(这里使用mysql-5.7版本)
  • 之前项目操作数据库,都是使用root用户,root用户权限太高了,在公司里,一般不会给你root用户权限
  • 如果开发人员是root权限,数据安全性就很差
  • 在mysql中创建一个luffy库,再创建luffy用户,给用户授予luffy库的所有权限,即luffy用户只对luffy库有操作权限

步骤一

  • 管理员连接数据库(密码为自己设置的密码)

    mysql -uroot -p密码

步骤二

  • 创建数据库

    create database luffy default charset=utf8;

步骤三

  • 查看用户目前已有的用户

    select user,host,password from mysql.user;

    如果没有创建过别的用户,这里只会显示root用户的信息

    5.7以后的版本使用的命令如下:

    select user,host,authentication_string from mysql.user;

    ppP9y6S.png

步骤四

  • 创建路飞用户,并授予luffy库所有权限

    如何设置权限账号密码?

    授权账号命令:
    grant 权限(create, update) on 库.表 to '账号'@'host' identified by '密码'
  • 配置任意ip都可以连接数据库的账户

    grant all privileges on luffy.* to 'luffy'@'%' identified by 'Luffy123?';

步骤五

  • 由于数据库版本的问题,可能本地还连接不上,就给本地用户单独配置

    grant all privileges on luffy.* to 'luffy'@'localhost' identified by 'Luffy123?';

    ppPPORx.png

步骤六

  • 配置完账号信息后还需要刷新一下权限,因为此时我们的配置信息是写在文件中的,刷新权限后就会让他加载到内存中运行

    flush privileges;

    最后我们得到了只能操作luffy数据库的用户

    账号:luffy
    密码:Luffy123?

    使用不同的用户,能操作的表也是不同的:

    root用户

    ppPiIpt.png

    luffy用户

    ppPFIUJ.png

2、本地连接数据库和使用ip连接数据库的区别

img

img

通过上面的查看已有用户的命令,我们可以看到用户的信息,其中的host信息代表的就是用不同的方式连接数据库时的配置。

如果host为%号,表示所有的远程路由都可以访问

3、使用项目连接库

mysqlclient模块的选择

项目操作mysql,需要使用模块

-pymysql
-mysqlDB
-mysqlclient
  • 如果我们直接运行项目会报错,django默认使用mysqlDB操作mysql,mysqlDB这个模块,在python2可以,在python3中不支持,于是咱们使用pymysql替换,到了django2.0.7以后,如果使用pymysql替换,需要修改django的源代码,后期使用mysqlclient,替换pymysql,mysqlclient是mysqlDB的python3.x版本

  • 如果使用pymysql,需要修改源码,需要执行(这段代码的作用我们称之为猴子补丁)

    import pymysql
    pymysql.install_as_MySQLdb() # 猴子补丁
  • 猴子补丁

    猴子补丁,把里面所有mysqlDB的对象,都替换成pymysql

    猴子补丁是:在程序运行过程中得到动态替换技术

    以后在django中不使用pymysql了,使用mysqlclient,不需要再执行任何补丁了

    win,linux,mac,这个模块不太好装,看人品,有时候很顺利,有时候装不上

  • 统一使用mysqlclient来操作mysql的底层库,一切都解决了

    -统一使用mysqlclient来作为操作mysql的底层库
    -基于py2的mysqldb,在py3上重新了,但是名字改成了mysqlclient
    -使用mysqlclient,只需要安装这个模块,不需要再写任何代码,直接用即可
    -但是:mysqlclient 这个模块,不好装
    -win 一般人品好,人品好,pip install mysqlclient
    -人品不好,装不了,centos部署项目,后面会讲centos上如何装
  • mysqlclient安装

    pip install mysqlclient
    也可以使用pycharm安装

4、pycharm连接数据库

安装了mysqlclient后,需要在配置文件dev.py中进行配置:

'修改数据库配置'
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'luffy',
'USER': 'luffy',
'PASSWORD': 'Luffy123?',
'HOST': 'localhost',
'PORT': 3306
}
}
'如果使用的是pymysql,需要额外添加这些代码'
import pymysql
pymysql.install_as_MySQLdb()

在配置数据库信息的时候,我们考虑到用户名跟密码写死了,并不安全

可能存在的风险

如果我们的源代码泄露了->数据库用户名密码就泄露->黑客可以远程登录->脱库(就是数据库被人家偷了)
-华住汉庭的酒店入住信息泄露,源代码泄露了,导致被脱库
-上海随身办的数据泄露

因此这里可以使用环境变量来动态存储用户名和密码,修改后的代码如下:

# 用户名密码写死在代码中了,为保证安全,使用环境变量存取
# os.environ可以获取到环境变量中的数据
# 这里我们设置的是通过环境变量的名称获取用户密码,如果不存在就使用默认的值
name = os.environ.get('LUFFY_NAME', 'luffy')
password = os.environ.get('LUFFY_PASSWORD', 'Luffy123?')
# 拓展:有的公司,直接有个配置中心---》服务--》只用来存放配置文件
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'luffy',
'USER': name,
'PASSWORD': password,
'HOST': '127.0.0.1',
'PORT': 3306
}
}

配置好之后在pycharm中连接数据库

img

五、软件开发模式

瀑布模式

bbs项目就是按照这种模式,现在已经用的不多了

-需求分析---》设计--》创建数据库 所有都创建---》开发(3个月)---》交给测试--》测试通过---》上线

敏捷开发

-需求分析---》设计---》只设计一个板块---》开发(2周)---》交给测试---》运维上线(测试环境)
-设计---》只设计一个板块---》开发(2周)---》交给测试---》运维上线(测试环境)
-一个sprint周期
-scrum敏捷项目管理

img

六、User模块User表配置,开放media访问

提示:当你决定使用auth表扩写,项目一定不要先迁移,先建好用户表再迁移

如果已经迁移完了,再想用auth的user表,操作很复杂:
-删库,删迁移文件所有app
-删admin和auth的迁移文件

因为我们在扩写auth表的时候添加了头像字段,存储了图片,因此我们需要导入pillow模块

pip install Pillow

接着我们去user app的models.py中扩写一个User表

from django.db import models
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
# 扩写手机号和头像字段
mobile = models.CharField(max_length=11, unique=True)
# 需要pillow包的支持
icon = models.ImageField(upload_to='icon', default='icon/default.png')
class Meta:
db_table = 'luffy_user'
verbose_name = '用户表'
verbose_name_plural = verbose_name
def __str__(self):
return self.username

接着我们需要去配置文件中更换auth模块使用的用户表

dev.py

# 自定义用户表配置
AUTH_USER_MODEL = 'user.User'

之后我们在迁移数据库的时候会报错,报错提示是说找不到小luffy_api的环境变量,这是因为在配置文件中配置环境变量的时候,小luffy_api的配置代码如下:

sys.path.insert(0, BASE_DIR)

这时候我们使用os.environ可以发现跟别的环境变量相比,小luffy_api的环境变量是一个对象,因此我们需要改变写法为:

sys.path.insert(0, str(BASE_DIR))

数据库迁移命令:

执行迁移命令前,需要从cmd界面中进去manage.py文件所在的目录

python38 manage.py makemigrations python38 manage.py migrate

数据库迁移成功结果如下:

img

七、django的配置文件讲解

在配置文件的最上方我们看到他导入了pathlib模块

from pathlib import Path

作用:3.6 以后,处理文件路径的模块,原来是用os模块拼接路径

from pathlib import Path
import os
import sys
# 项目根路径
# 我们就是要让小路飞路径作为项目根路径
BASE_DIR = Path(__file__).resolve().parent.parent # 项目根路径, 小路飞luffy_api路径 D:\pythonProject03\luffy_api\luffy_api
# print(BASE_DIR)
# 把 apps 路径加入到环境变量
sys.path.insert(0, os.path.join(BASE_DIR, 'apps'))
# 把BASE_DIR也加入到环境变量,以后直接从小路飞开始导起即可
sys.path.insert(0, str(BASE_DIR))
# print(sys.path)
# 以后从大路飞开始导起,或者小路飞开始导起,或者apps开始导起都可以
# 秘钥,涉及到加密的django中,都会用它
SECRET_KEY = 'django-insecure-!g(8l%fw_#t$pz$x4jdf#e3$b4+c%xzqyq@3zki08vj&i)z4k-'
# 项目是以debug模式运行,还是非debug模式运行
# 项目上线,要改成false
# debug=True 代码可以热更新
# 调试模式下,对开发者更友好:可以列出所有路径.报了错,前端能看到
DEBUG = False
# ALLOWED_HOSTS = ['*']需要搭配debug=False,它的意思是,允许我的项目部署在哪个ip地址上,* 表示允许部署在所有地址上
ALLOWED_HOSTS = ['*']
# django 是多个app组成的,里面配置app,默认带的app,django内置的app
# django 是一个大而全的框架,有很多内置app:
# admin后台管理,
# auth权限管理,
# contenttypes表中存app也表的关系,
# sessions session表,django的session相关
# messages:消息框架,flask讲闪现,是一样的东西
# staticfiles:静态资源的
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
# 'luffy_api.apps.home', # luffy_api在环境变量,直接从这一层开始导起, 太长了,以后就想 注册 home
# 'luffy_api.apps.user'
'home',
'user'
]
# 中间件
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware', # 安全相关中间件
'django.contrib.sessions.middleware.SessionMiddleware', # session相关中间件
'django.middleware.common.CommonMiddleware', # 带不带 / 问题
'django.middleware.csrf.CsrfViewMiddleware', # csrf 认证,生成csrf串
'django.contrib.auth.middleware.AuthenticationMiddleware', # 用户认证
'django.contrib.messages.middleware.MessageMiddleware', #消息框架相关
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
# 根路由
ROOT_URLCONF = 'luffy_api.urls'
# 模板文件
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [BASE_DIR / 'templates'], # 坑,模板路径用列表,可以有多个
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
# 项目运行的配置---》项目上线运行,使用uwsgi 运行 application()
WSGI_APPLICATION = 'luffy_api.wsgi.application'
# 用户名密码写死在代码中了,保证安全
name = os.environ.get('LUFFY_NAME', 'luffy')
password = os.environ.get('LUFFY_PASSWORD', 'Luffy123?')
# 拓展:有的公司,直接有个配置中心---》服务--》只用来存放配置文件
# 数据库配置,mysql 主从搭建完,读写分离
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'luffy',
'USER': name,
'PASSWORD': password,
'HOST': '127.0.0.1',
'PORT': 3306
},
}
#忽略掉
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# 国际化
LANGUAGE_CODE = 'zh-hans'
TIME_ZONE = 'Asia/Shanghai'
USE_I18N = True
USE_L10N = True
USE_TZ = False
# 静态资源
STATIC_URL = '/static/'
# 这是后面版本才有的配置,更改了id字段的字段类型(更大了)
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'

八、开启media访问

因为我们需要存储用户的头像,因此需要实现自定义开放接口给前端访问

步骤一

在配置文件中添加media的配置信息

MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

步骤二

在总路由中注册,这里也不是非要使用re_path

from django.views.static import serve
# 导入配置文件--->如果你配了,用你的,如果没配,用内置的
from django.conf import settings
urlpatterns = [
# 开启media访问
# re_path('^media/(?P<path>.*)', serve, {'document_root': settings.MEDIA_ROOT}),
path('media/<path:path>', serve, {'document_root': settings.MEDIA_ROOT})
]
"""
转换器的第一个path是匹配的方式(也可以说类型吧),第二个path是传入到视图函数中的参数名称
路由中的serve起到传递参数给视图函数的作用,并且能找到视图函数或类的位置拿到结果(这样的功能建议研究一下,可能有些情况需要我们自行编写)
"""

在给media注册路由的时候我们会导入配置文件,我们可以根据配置文件的路由直接导入配置文件,也可以使用这里的

from django.conf import settings

导入,在使用这种方式导入的时候,如果我们没有配置配置文件,就会使用内置的自带的配置文件,如果我们写了配置文件,就会优先使用我们的配置文件,以后都使用这种方式

配置成功之后,就可以在浏览器中使用路由打开图像

ppPQYCT.png

九、扩展

# 期终架构相关
-前端---》看人家开源的前端项目,看不懂
-第一种情况,vue+java====》分析有哪些接口,drf复写出来
-第二种情况: 你新建前端项目,你看到它哪个页面好看,copy你里面去只要template和style
-js东西自己写
# https://zhuanlan.zhihu.com/p/370167569
# windows安装 mysql 5.7
https://zhuanlan.zhihu.com/p/571585588

前后端分离的rbac项目演示

# 后台:https://gitee.com/liuqingzheng/rbac_manager
# 前端:https://gitee.com/liuqingzheng/vue_admin

项目演示

# 登录
# 系统管理
-用户管理
-角色管理
-菜单管理
-部门管理
-岗位管理
# 最核心
-创建了用户,授予了角色,因为角色有权限,这个用户就有权限
-如果这个用户有权限,进入到系统,就能看到相关的操作,如果没有权限,就不能操作

面试题,md5是对称加密还是非对称加密(题目没什么含金量)

# 面试题,md5是对称加密还是非对称加密
-对称加密:加密的秘钥和解密的秘钥是同一个
-非对称加密:加密使用公钥加密,解密使用私钥解密,使用公钥是不能解密的
-摘要算法:没有解密这一说
posted @   dear丹  阅读(191)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示