路飞项目的前期准备
目录
软件开发流程
企业软件开发流程
# 真正的企业里软件从立项到交付整个过程
-立项:确定公司要开发这个软件 公司高层
-软件来源
-产品经理设计出来的----》互联网项目 互联网公司
-用户(医院,政府部门,企业。。) 传统软件公司
-需求分析
# 互联网项目
-需求调研和分析:产品经理设计出来的
# 传统软件
-需求调研和分析:市场人员跟客户对接
-产品经理 ,开发人员跟客户对接,生成需求文档
-原型设计:产品经理
-懂业务
-画出原型图:app,网页款
-分任务开发
-UI设计
-根据原型图设计 切图
-前端团队
-前端拿着切图写代码(pc,小程序,移动端)
-mock数据:搞假数据,先把功能开发出来
-后端团队
-组里开会,需求文档和原型图,设计后台
-架构,数据库设计
-分任务开发:用户,商品板块
-测试(质量控制部)
-普通功能测试
-接口测试
-压力测试,jmeter
-自动化测试
-联调测试
-项目上线(运维)
-持续维护项目
后端开发,公司开发流程
# 作为后端开发,公司里开发的流程
-开新项目,先开会,设计技术选型,数据库设计
-产品,原型图做好了
-老大在项目管理平台(禅道)分配任务给我
-进入到管理平台就能看到任务,相关功能的原型图
-需求,原型图,实现的效果
-开发---有不明白的需求,找产品对接----》自测
-提交到版本仓库(git,svn)
-管理平台点完成
-所有都开发完了,分支合并
-跟前端联调
-发版
-如果是老项目
-老大在项目管理平台(禅道)分配任务给我
-进入到管理平台就能看到任务,相关功能的原型图
-需求,原型图,实现的效果
-开发---有不明白的需求,找产品对接----》自测
-提交到版本仓库(git,svn)
-所有都开发完了,分支合并
-跟前端联调
-发版
路飞项目需求
关于路飞项目
-商城类
-知识付费项目
-主站vue
-后台管理 simpleui
需求
-首页功能
-首页轮播图
-推荐课程
-用户功能
-用户名密码登录
-手机号验证码登录
-发送手机验证码
-验证手机号是否注册过
-注册接口
-查看用户信息(自己写)
-修改用户信息(自己写)
-课程列表功能
-课程列表接口,课程列表展示
-排序,过滤,分页
-课程详情
-课程详情接口
-视频播放功能
-视频托管(第三方,自己平台)文件托管
-下单功能
-支付宝支付,生成支付链接,付款,回调修改订单状态
-购买成功功能
pip永久换源
pip3 install django
-第三方开发者,开发了第三方模块,把模块打包传到了pypi上
-根据名字,把这个打包好的模块下载下来
-以下在公司中出现的情况
-公司不能上外网
-xx.whl 文件提交下好,再安装--》pip install 路径/xx.whl
-已经有项目,模块装完了,想把这个项目所有的模块导出---》导入到别的项目
-可以顺利上外网
下载会很慢,因为在国外
国内有些镜像站:建议用阿里云
Windows换源操作
"""换源操作"""
# 配置本地镜像站为阿里云,以后只要pip install 就是去阿里云下载
- 1、文件管理器文件路径地址栏敲:%APPDATA% 回车,快速进入 C:\Users\电脑用户\AppData\Roaming 文件夹中
-2、新建 pip 文件夹并在文件夹中新建 pip.ini 配置文件
-3、新增 pip.ini 配置文件内容
[global]
index-url = https://mirrors.aliyun.com/pypi/simple
[install]
use-mirrors =true
mirrors =https://mirrors.aliyun.com/pypi/simple
trusted-host =mirrors.aliyun.com
MacOS、Linux换源操作
1、在用户根目录下 ~ 下创建 .pip 隐藏文件夹,如果已经有了可以跳过
-- mkdir ~/.pip
2、进入 .pip 隐藏文件夹并创建 pip.conf 配置文件
-- cd ~/.pip && touch pip.conf
3、启动 Finder(访达) 按 cmd+shift+g 来的进入,输入 ~/.pip 回车进入
4、新增 pip.conf 配置文件内容
[global]
index-url = https://mirrors.aliyun.com/pypi/simple
[install]
use-mirrors =true
mirrors =https://mirrors.aliyun.com/pypi/simple
trusted-host =mirrors.aliyun.com
虚拟环境
# 虚拟环境是什么?
-有个系统环境 安装的python3.8 ,装模块,都装在 解释器文件夹的Lib\site-packages
-现在有两个django项目,一个基于django3 写的,一个基于django2 写的
-把两个项目都打开,同时开发
-每个项目都用自己独立的环境,装的模块相互不影响
-两种解决方案:
Virtualenv
pipenv
# 如何安装和配置
-1 安装两个模块
pip3 install virtualenv # 虚拟环境是它
pip3 install virtualenvwrapper-win # 对虚拟环境的加强,以后只需要简单的命令就可以使用和创建虚拟环境
-2 配置虚拟环境管理器工作目录
-在环境变量中新建:WORKON_HOME: D:\Virtualenvs
-在D盘创建文件夹,以后新建的虚拟环境,都会在这个文件夹下
-3 去向Python3的安装目录 => Scripts文件夹 => virtualenvwrapper.bat => 双击
# 如何创建和使用虚拟环境
-创建并进入到虚拟环境: 创建一个虚拟环境叫luffy,会放在D:\Virtualenvs
mkvirtualenv -p python3 luffy
-cmd 窗口中带着虚拟环境名字,表示在虚拟环境中,以后安装的所有模块,都是给虚拟环境安装的
-退出虚拟环境
deactivate
-查看有哪些
workon
-进入虚拟环境
workon luffy
-删除虚拟环境
rmvirtualenv 虚拟环境名称
# 本地有了虚拟环境,pycharm使用虚拟环境
-已有项目,配置虚拟环境如何做
-新建项目,使用已有虚拟环境
django-admin
pycharm创建
# 了解 使用pycharm创建虚拟环境
-新建项目,新建虚拟环境
路飞项目前后端创建
# 创建路飞后端
-创建路飞项目前,虚拟环境中先装好 django 3.2.2
-选中虚拟环境,起名叫luffy_api
# 前端项目创建
vue create luffy_city
包导入
模块和包的区别
-模块就是一个py文件
-包是一个文件夹下有__init__.py里面有很多py文件
-以后下载第三方包或自己写包,如何导入
python 导入包
-pycharm会把项目路径加入到环境变量,命令行中不会加入
-from 的路径,需要从环境变量开始
-安装的第三方模块,都在环境变量
-内置模块,os,sys也在环境变量中,可以直接导入
-在包内部,推荐使用相对导入
-一旦使用相对导入,该文件就不能以脚本形式运行了(不能右键运行)
-在同一个目录下的推荐使用相对导入
-不同目录下的推荐使用绝对导入
后端项目调整目录
# 调整目录后成
"""
├── luffy_api
├── logs/ # 项目运行时/开发时日志目录 - 包
├── manage.py # 脚本文件
├── luffy_api/ # 项目主应用,开发时的代码保存 - 包
├── apps/ # 开发者的代码保存目录,以模块[子应用]为目录保存 - 包
├── libs/ # 第三方类库的保存目录[第三方组件、模块] - 包
├── settings/ # 配置目录 - 包
├── dev.py # 项目开发时的本地配置
└── prod.py # 项目上线时的运行配置
├── urls.py # 总路由
└── utils/ # 多个模块[子应用]的公共函数类库[自己开发的组件]
└── scripts/ # 保存项目运行时的脚本文件,小的测试脚本 - 文件夹,不提交到git上
"""
调整后运行不了
1.原因:找不到配置文件---》django项目运行,第一步就要加载配置文件
-开发阶段:python manage.py run server---》找不到配置文件就报错---》开manage.py
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'djangoProject14.settings.dev')
# 这里的sev其实是原来的settings配置改名后的文件
-上线阶段:uwsgi运行----》
asgi.py
wsgi.py
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'luffy_api.settings.prod')
2.项目能运行
-创建app
-python manage.py startapp home 命令在哪执行,app就创建在哪
-cd到apps路径下创建app
-python ../../manage.py startapp app名字
-注册app
-首先在app下的apps.py修改name(后面就可以不改了)
-以后想直接写app名字,所以要把apps的路径加入到环境变量中,加载配置文件的一开始
-在配置文件中把apps和小路飞路径加入到环境变量
BASE_DIR = Path(__file__).resolve().parent.parent # 小项目的路径
path = os.path.join(BASE_DIR, 'apps') # 将apps的路径加入小项目的路径中
sys.path.insert(0, path) # 将apps的路径加入系统环境变量
sys.path.insert(0, BASE_DIR) # 将小羡慕的路径添加系统环境变量
-导入模块,编辑机爆红,爆红不一定是真的错
-把加入到环境变量的路径,右键,做为source root
后台日志封装
项目肯定要记录日志的
-日志可以打印到控制台
-日志可以写到日志文件中
-日志存到某个库中
-所有项目日志统一管理 sentry:django写的服务,收集日志的
# 以后,在项目中不要出现print了,以后都用日志 logger.info(),以后项目上线,只需要调整日志级别,低级别的日志就不打印了,于是日志输出不用删掉
操作步骤:django中集成日志步骤,django使用的就是python内置的日志模块
-1.在配置文件中加入日志配置 ---大字典
-2.utils新建 common_logger.py,得到日志对象
import logging
logger = logging.getLogger('django')
-3.在任意想用日志的地方,导入使用即可
from utils.comment_logger import logger
logger.info('info级别的日志')
logger.error('error级别的日志')
日志配置代码
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': 'INFO',
'filters': ['require_debug_true'],
'class': 'logging.StreamHandler',
'formatter': 'simple'
},
'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, # 是否让日志信息继续冒泡给其他的日志处理系统
},
}
}
前后端分析的rbac项目演示
# 后台:https://gitee.com/liuqingzheng/rbac_manager
# 前端:https://gitee.com/liuqingzheng/vue_admin
全局异常处理封装
前端 要接收的格式,要统一无论后端是否出错
三大认证,视图类的方法只要出了异常,就会执行一个函数,但是这个函数只能处理drf异常---》我们需要自己写个函数,既能处理drf异常,又能处理django异常,这样统一返回格式,前端看到格式都统一
使用步骤:
1.在utils中新建 common_exceptions.py
2.写个函数
3.配置文件,以后只要出了异常,都会走咱们的函数
4.REST_FRAMEWORK = {
'EXCEPTION_HANDLER': 'utils.common_exceptions.exception_handler',
}
5.勇敢大胆写代码,即便报错,程序不会蹦,并且会记录日志,并且处理成统一格式
全局异常处理代码
from rest_framework.views import exception_handler as drf_exception_handler
from rest_framework.response import Response
from .common_logger import logger
def exception_handler(exc, context):
# 记录日志:哪个ip地址,用户id是多少,访问哪个路径,执行哪个视图函数,出了什么错
# 获取当前用户的request对象
request = context.get('request')
# 获取用户访问的视图
view = context.get('view')
# 获取用户的ip地址
ip = request.META.get('REMOTE_ADDR')
# 获取用户的id
user_id = request.user.pk
# 获取用户访问的路径
path = request.get_full_path()
# 执行原来的drf异常捕获
response = drf_exception_handler(exc, context)
# 如果有值,则证明是drf的异常,原来的函数返回的是一个response对象
if response:
logger.warning('drf出了异常,异常是【%s】' % str(exc))
res = Response({'code': '999', 'msg': response.data.get('detail')})
# 没有值,则证明是其他异常
else:
logger.error('用户【%s】,ip地址【%s】,访问地址为【%s】,执行视图函数为【%s】,出错是【%s】' % (user_id, ip, path, view, str(exc)))
res = Response({'code': '101', 'msg': '服务器异常,请联系管理员'})
return res
封装Response
本身drf有Response,但是有的公司会规定,前端收到的格式都是固定的
-{'code':'100','msg':{'data':}}
-{code:100,msg:提示,token:asdfasd,user:lqz}
对Response进行封装,封装后,code,msg可以不传,不传就用默认的
使用步骤:
1.在utils下新建common_response.py
2.封装APIResponse
3.导入使用,视图函数的办法,返回时,都使用自己的
封装的代码
from rest_framework.response import Response
class APIResponse(Response):
def __init__(self, code=100, msg='成功', status=None, headers=None, **kwargs):
data = {'code': code, 'msg': msg}
# 如果kwargs有值,证明接收到了token或者其他的什么字典
if kwargs:
data.update(kwargs) # 这里使用字典更新的方法
super().__init__(data=data, status=status, headers=headers) # 子类调用父类的方法
luffy数据库创建
创建用户创建库
创建luffy数据库
之前项目操作数据库,都是使用root用户,root用户权限太高了,在公司里,一般不会给你root用户权限
# 如果开发人员是root权限,数据安全性就很差
# 开发人员,专门创建一个用户,用户只对当前项目的库有操作权限
# 创建一个luffy库,创建luffy用户,luffy用户支队luffy库有操作权限
创建luffy数据库
"""
1.管理员连接数据库
mysql -uroot -p
2.创建数据库
create database luffy default charset=utf8
3.查看用户
select user,host,password from mysql.user;
只有root用户,要创建luffy用户
5.7版本往后查看用户:
select user,host,authentication_string from mysql.user;
"""
创建路飞用户,授予luffy库所有权限
"""
设置权限账号密码:grant 权限(create,update) on 库.表 to '账号'@'host' identified by '密码'
1.配置任意ip都可以连入数据库的账户
grant all privileges on luffy.* to 'luffy'@'%' identified by 'Luffy123?';
2.由于数据库版本的问题,可能本地还连接不上,就给本地用户单独配置
grant all privileges on luffy.* to 'luffy'@'localhost' identified by 'Luffy123?';
3.刷新一下权限
>: flush privileges;
只能操作luffy数据库的账户
账号:luffy
密码:Luffy123?
"""
使用项目连接库
# 项目操作mysql,需要安装模块
-pymysql
-mysqlDB
-mysqlclient
-历史:原来py2上有个操作mysql的模块叫mysqlDB,但到py3,没有支持py3,django默认使用这个模块去连接mysql,默认使用-mysqlDB连接,-mysqlDB不支持py3,运行报错
-我们使用pymysql,作为连接mysql的数据库模块,但是需要加代码
imprort pymysql
pymysql.install_as_mysqldb() # 猴子补丁
-django 2.2.2以后,还使用pymysql,需要改djagno源代码
-统一使用mysqlclient来作为操作mysql的底层库
-基于py2的mysqldb,在py3上重新了,但是名字改成了mysqlclient
-使用mysqlclient,只需要安装这个模块,不需要再写任何代码,直接用即可
-但是:mysqlclient 这个模块,不好装
-win 一般人品好,人品好,pip install mysqlclient
-人品不好,装不了,centos部署项目,后面会讲centos上如何装
# mysqlclient
pip install mysqlclient
###### 配置文件修改,连接mysql,使用路飞用户
# 用户名密码写死在代码中了,保证安全
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
}
}
软件开发模式
# 瀑布模式:bbs项目就是按照这种模式
-需求分析---》设计--》创建数据库 所有都创建---》开发(3个月)---》交给测试--》测试通过---》上线
# 敏捷开发
-需求分析---》设计---》只设计一个板块---》开发(2周)---》交给测试---》运维上线(测试环境)
-设计---》只设计一个板块---》开发(2周)---》交给测试---》运维上线(测试环境)
-一个sprint周期
-scrum敏捷项目管理
User模块用户表
# 你决定使用auth表扩写,项目一定不要先迁移,先建好用户表再迁移
已经迁移完了,再想用auth的user表
-删库,删迁移文件所有app
-删admin和auth的迁移文件
# 用户表使用auth表扩写 pip install Pillow
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
# 遇到的问题,明明小luffyapi已经加入到环境变量,程序运行没问题,但是表迁移,就报错,找不到模块
-打印了看一下,确实环境变量有,但是不是个字符串,是个对象
-程序运行,是没问题
-迁移有问题:配置文件中转成字符串,就解决了
django的配置文件
# pathlib # 3.6 以后,处理文件路径的模块,原来是os,
# 面试题,md5是对称加密还是非对称加密
-对称加密:加密的秘钥和解密的秘钥是同一个
-非对称加密:加密使用公钥加密,解密使用私钥解密,使用公钥是不能解密的
-摘要算法:没有解密这一说
# 运行django ,泡在0.0.0.0上,局域网内,所有人都能访问
from pathlib import Path
import os
import sys
BASE_DIR = Path(__file__).resolve().parent.parent # 小项目的路径
path = os.path.join(BASE_DIR, 'apps') # 将apps的路径加入小项目的路径中
sys.path.insert(0, path) # 将apps的路径加入系统环境变量
sys.path.insert(0, str(BASE_DIR)) # 将小羡慕的路径添加系统环境变量
# 秘钥,涉及到加密的django中,都会用它
SECRET_KEY = 'django-insecure-=4$gy3wqi9q3!&_%)ff#6zmelv3+iyjwe8u9vmgnipp@jien9n'
# 项目是以debug模式运行,还是非debug模式运行
# 项目上线,要改成false
# debug=True,代码可以热更新
# 挑食模式下,对开发者更友好,可以列出所有路径,报了错,前端能看到
DEBUG = True
# 它搭配debug=False,它的意思是,允许我的项目部署在哪个ip地址上,* 表示允许部署在所有地址上
# ALLOWED_HOSTS = ['*']
ALLOWED_HOSTS = []
# jango是多个app组成的,里面配置app,默认带的app,django内置的app
# django是一个大而全的框架,有很多内置app
# admin是后台管理
# auth是权限管理
# contenttypes表中存app表的关系
# sessions 里面有session表,django的session相关
# messages 消息框架,flask讲闪现,是一样的东西
# staticfiles:静态文件资源
INSTALLED_APPS = [
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions 里面有session表,django的session相关
'django.contrib.messages',
'django.contrib.staticfiles',
'home',
'user',
'rest_framework',
]
# 中间件
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
# 安全相关中间件
'django.contrib.sessions.middleware.SessionMiddleware',
# session相关中间件
'django.middleware.common.CommonMiddleware',
# 路由地址带不带/问题
'django.middleware.csrf.CsrfViewMiddleware',
# scrf认证,生成scrf串
'django.contrib.auth.middleware.AuthenticationMiddleware',
# 用户认证相关
'django.contrib.messages.middleware.MessageMiddleware',
# 消息框架相关
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
# 根路由
ROOT_URLCONF = 'djangoProject14.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 = 'djangoProject14.wsgi.application'
# 数据库用户名密码卸载在代码中,保证安全
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
}
}
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 = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# 静态资源
STATIC_URL = '/static/'
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
# 日志配置
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': 'INFO',
'filters': ['require_debug_true'],
'class': 'logging.StreamHandler',
'formatter': 'simple'
},
'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, # 是否让日志信息继续冒泡给其他的日志处理系统
},
}
}
# 全局异常
REST_FRAMEWORK = {
'EXCEPTION_HANDLER': 'utils.common_exceptions.exception_handler',
}
# 自定义auth表
AUTH_USER_MODEL = 'user.User'
开启media访问
# 配置文件加入
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
# 总路由中设置
# re_path('^media/(?P<path>.*)', serve, {'document_root': settings.MEDIA_ROOT})
path('media/<path:path>', serve, {'document_root': settings.MEDIA_ROOT})
# 访问
http://127.0.0.1:8000/media/icon/default.png
# 以后使用djagno的配置文件都用这个
from django.conf import settings
扩展
# 期终架构相关
-前端---》看人家开源的前端项目,看不懂
-第一种情况,vue+java====》分析有哪些接口,drf复写出来
-第二种情况: 你新建前端项目,你看到它哪个页面好看,copy你里面去只要template和style
-js东西自己写
# https://zhuanlan.zhihu.com/p/370167569
# windows安装 mysql 5.7
https://zhuanlan.zhihu.com/p/571585588
老刘项目演示
# 登录
# 系统管理
-用户管理
-角色管理
-菜单管理
-部门管理
-岗位管理
# 最核心
-创建了用户,授予了角色,因为角色有权限,这个用户就有权限
-如果这个用户有权限,进入到系统,就能看到相关的操作,如果没有权限,就不能操作
路飞前台全局css,全局配置文件
整理项目
App.vue
<template>
<div id="app">
<router-view/>
</div>
</template>
router/index.js
const routes = [
{
path: '/',
name: 'home',
component: HomeView
},
]
HomeView.vue
<template>
<div class="home">
<h1>首页</h1>
</div>
</template>
<script>
export default {
name: 'HomeView',
}
</script>
全局css
正常写前端项目,需要去掉所有标签的默认样式,css
第一步:在assets文件下新建一个css文件---新建global.css
/* 声明全局样式和项目的初始化样式 */
body, h1, h2, h3, h4, h5, h6, p, table, tr, td, ul, li, a, form, input, select, option, textarea {
margin: 0;
padding: 0;
font-size: 15px;
}
a {
text-decoration: none;
color: #333;
}
ul {
list-style: none;
}
table {
border-collapse: collapse; /* 合并边框 */
}
# 第二步:全局生效 main.js中配置
// 使用全局css样式,只需要导入就会生效
import '@/assets/css/global.css'
全局js
想后端发送请求,请求地址测试阶段 127.0.0.1::8000 ---》后期上线,地址要变,如果在组件中把地址写死,以后要改每个都要改
写一个全局js,js中有个url地址,以后所有组件中发送请求时,都是用这个url地址
# 导入导出
使用步骤:
1.新建:在assets文件下新建js文件---》新建setthings.js
export default {
BASE_URL:'http://127.0.0.1:8000/api/v1'
}
2.在main.js中引入
//引入settings.js 把setting对象放入到vue的原型中
import settings from "@/assets/js/settings";
Vue.prototype.$settings = settings
//以后在任意组件中只需要 this.$settings.BASE_URL
3.在任意组件中使用
this.$settings.BASE_URL
this.$axios.get(this.$settings.BASE_URL+'/users').then(res=>{
})
安装axios
跟后端交互
# 使用步骤:
1.安装:cnpm install axios -S
2.把axios放到vue原型中,main.js中
import axios from "axios";
Vue.prototype.$axios=axios
3.在任意组件中使用
this.$ajax.get()
安装vue-cookies
后期登录成功,token存在cookie中
使用步骤:
1.安装:cnpm install vue-cookies -S
第二步:把vue-cookies放到vue原型中,main.js中
import cookies from "vue-cookies";
Vue.prototype.$cookies=cookies
第三步:在任意组件中使用
this.$cookies.set()
this.$cookies.set()
安装elementui
# 样式,使用elementui
# 使用步骤:
第一步:安装 cnpm install element-ui -S
第二步:main.js配置
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI);
第三步:复制,粘贴
后台主页模块表设计
# 分析完原型图,首先要写接口
-轮播图接口
-推荐课程接口(暂时没写)
-推荐老师接口(无)
-学员评论(无)
创建首页app,home
-来到apps文件夹下执行
-python ../../manage.py startapp home
-创建表model,轮播图表Banner
创建表步骤;
1.因为有些字段是多个表都要写字段,所以我们将这些字段统一写在一个父类中,在utils下创建common_model.py
from django.db import models
class BaseModel(models.Model):
created_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
updated_time = models.DateTimeField(auto_now=True, verbose_name='最后更新时间')
is_delete = models.BooleanField(default=False, verbose_name='是否删除')
is_show = models.BooleanField(default=True, verbose_name='是否上架')
orders = models.IntegerField(verbose_name='优先级')
class Meta:
abstract = True # 只用来继承,不用来在数据库创建
2.在home的app的model.py写模型类
class Banner(BaseModel):
# 哪些字段:真正图片地址,标题,跳转链接,图片介绍 是否删除(软删除),是否显示,优先级,创建时间,更新事件:公共字段
title = models.CharField(max_length=16, unique=True, verbose_name='名称')
image = models.ImageField(upload_to='banner', verbose_name='图片')
link = models.CharField(max_length=64, verbose_name='跳转链接')
info = models.TextField(verbose_name='详情')
class Meta:
db_table = 'luffy_banner'
verbose_name_plural = '轮播图表'
def __str__(self):
return self.title
-3.迁移
python manage.py makemigrations
python manage.py migrate
后台主页模块轮播图接口
轮播图接口,给首页用
视图层
from rest_framework.viewsets import GenericViewSet
from rest_framework.mixins import ListModelMixin
from .models import Banner
from .serializer import BannerSerializer
from utils.common_response import APIResponse
class BannerView(GenericViewSet, ListModelMixin):
queryset = Banner.objects.filter(is_delete=False, is_show=True).order_by('orders')
serializer_class = BannerSerializer
def list(self, request, *args, **kwargs):
res = super().list(request, *args, **kwargs)
return APIResponse(data=res.data) # {code:100,msg:成功,data=[{},{}]}
序列化类
from rest_framework import serializers
from .models import Banner
# Form类和ModelForm的区别
class BannerSerializer(serializers.ModelSerializer):
class Meta:
model = Banner
fields = ['id', 'image', 'title', 'link']
路由
from rest_framework.routers import SimpleRouter
from . import views
router = SimpleRouter()
# 访问 http://127.0.0.1:8000/api/v1/home/banner ---->get 请求就可以查询所有轮播图
router.register('banner', views.BannerView, 'banner')
urlpatterns = [
]
urlpatterns += router.urls
录入数据
# 主站前后分离
# 后台管理使用django的admin做的---》simpleui
# 使用步骤;
1.安装simplenui:pip install django-simpleui
2.注册app:'corsheaders',
3.在home文件下admin.py中注册Banner表
from django.contrib import admin
from .models import Banner
admin.site.register(Banner)
4.录入数据:http://127.0.0.1:8000/admin
跨域问题详解
前端发送ajax请求,到后端,会有跨域的拦截
出现的原因
同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现
-请求的url地址,必须跟浏览器上的url地址处于同域上,也就是域名,端口,协议相同
-发送ajax请求的地址,必须跟浏览器上的url地址处于同域上,域[域名,地址,端口,协议]
-请求成功,数据库返回,但是浏览器拦截
补充:浏览器中输入域名:没有加端口
-www.baidu.com---->dns--->解析成地址 192.168.2.3----》没有加端口,默认是80
-dns解析,先找本地的host文件
-可以修改本地的host做映射
cors:scc.scrf
-跨域资源共享:后端计数,就是在响应头中加入固定的头,就会运行前端访问了
CORS基本流程
浏览器将CORS请求分成两类:简单请求(simple request)和非简单请求(not-so-simple request)。
浏览器发出CORS简单请求,只需要在头信息之中增加一个Origin字段。
浏览器发出CORS非简单请求,会在正式通信之前,增加一次HTTP查询请求,称为”预检”请求(preflight)。浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些HTTP动词和头信息字段。只有得到肯定答复,浏览器才会发出正式的XMLHttpRequest请求,否则就报错
# 什么是简单请求,什么是非简单请求?
# 符合如下条件,就是简单请求
(1) 请求方法是以下三种方法之一:
HEAD
GET
POST
(2)HTTP的头信息不超出以下几种字段:
Accept
Accept-Language
Content-Language
Last-Event-ID
Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain
# 演示简单和非简单请求
-如果是简单,直接发送真正的请求
-如果是非简单,先发送options,如果运行,再发真正的
自己解决跨域问题---》中间件
from django.utils.deprecation import MiddlewareMixin
class CorsMiddleWare(MiddlewareMixin):
def process_response(self,request,response):
if request.method=="OPTIONS": # 解决非简单请求的请求头
#可以加*
response["Access-Control-Allow-Headers"]="*"
# 允许前端的地址,所有请求头允许
response["Access-Control-Allow-Origin"] = "*"
return response
第三方模块解决跨域问题
1.安装:
pip install django-cors-headers
2.配置APP
INSTALLED_APPS = [
'corsheaders'
]
3.配置中间件
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware',
]
4.在配置文件配置
# 允许所有域
CORS_ORIGIN_ALLOW_ALL = True
# 允许的请求方式
CORS_ALLOW_METHODS = (
'DELETE',
'GET',
'OPTIONS',
'PATCH',
'POST',
'PUT',
'VIEW',
)
# 允许请求头中加的东西,如果请求头里面的键不在这里面还是会有跨域问题,所以要在这里面进行添加
CORS_ALLOW_HEADERS = (
'XMLHttpRequest',
'X_FILENAME',
'accept-encoding',
'authorization',
'content-type',
'dnt',
'origin',
'user-agent',
'x-csrftoken',
'x-requested-with',
'Pragma',
'token',
)
补充
# 以后在公司里,
后端一个项目
前端多个项目:主站一个,后台管理一个,app一个,小程序一个
前端一个项目
后端多个项目