准备环境
创建虚拟环境,安装依赖包----考虑版本适配问题
>virtualenv luffy
cd luffy\Script
activate
pip install django==2.2.2
pip install PymySQL
pip install Pillow
pip install django-redis==5.2.0
pip install djangorestframework==3.12.2
创建后端项目
django-admin startproject luffy
修改项目目录
G:.
└─luffy
├─logs
└─luffy
├─apps
├─settings
├─uploads
└─utils
修改环境变量
将配置文件更改为自定义目录下的配置文件
`os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'luffy.**settings.dev**')`
日志配置
在dev配置文件下添加日志配置
# 日志配置
LOGGING = {
'version': 1, #使用的python内置的logging模块,那么python可能会对它进行升级,所以需要写一个版本号,目前就是1版本
'disable_existing_loggers': False, #是否去掉目前项目中其他地方中以及使用的日志功能,但是将来我们可能会引入第三方的模块,里面可能内置了日志功能,所以尽量不要关闭。
'formatters': { #日志记录格式
'verbose': { #levelname等级,asctime记录时间,module表示日志发生的文件名称,lineno行号,message错误信息
'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': { #在debug=True下产生的一些日志信息,要不要记录日志,需要的话就在handlers中加上这个过滤器,不需要就不加
'()': 'django.utils.log.RequireDebugTrue',
},
'require_debug_false': { #和上面相反
'()': 'django.utils.log.RequireDebugFalse',
},
},
'handlers': { #日志处理方式,日志实例
'console': { #在控制台输出时的实例
'level': 'DEBUG', #日志等级;debug是最低等级,那么只要比它高等级的信息都会被记录
'filters': ['require_debug_true'], #在debug=True下才会打印在控制台
'class': 'logging.StreamHandler', #使用的python的logging模块中的StreamHandler来进行输出
'formatter': 'simple'
},
'file': {
'level': 'INFO',
'class': 'logging.handlers.RotatingFileHandler',
# 日志位置,日志文件名,日志保存目录必须手动创建
'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': { #和django结合起来使用,将django中之前的日志输出内容的时候,按照我们的日志配置进行输出,
'handlers': ['console', 'file'], #将来项目上线,把console去掉
'propagate': True, #冒泡:是否将日志信息记录冒泡给其他的日志处理系统,工作中都是True,不然django这个日志系统捕获到日志信息之后,其他模块中可能也有日志记录功能的模块,就获取不到这个日志信息了
},
}
}
异常处理
在utils下新建一个exceptions.py
from rest_framework.views import exception_handler
from django.db import DatabaseError
from rest_framework.response import Response
from rest_framework import status
import logging
logger = logging.getLogger('django')
def custom_exception_handler(exc, context):
"""
自定义异常处理
:param exc: 异常类
:param context: 抛出异常的上下文
:return: Response响应对象
"""
# 调用drf框架原生的异常处理方法
response = exception_handler(exc, context)
if response is None:
view = context['view']
if isinstance(exc, DatabaseError):
# 数据库异常
logger.error('[%s] %s' % (view, exc))
response = Response({'message': '服务器内部错误'}, status=status.HTTP_507_INSUFFICIENT_STORAGE)
然后在配置文件dev下添加异常处理
REST_FRAMEWORK = {
# 异常处理
'EXCEPTION_HANDLER': 'luffy.utils.exceptions.custom_exception_handler',
}
数据库
创建数据库
create database lyapi default charset=utf8mb4; -- utf8也会导致有些极少的中文出现乱码的问题,mysql5.5之后官方才进行处理,出来了utf8mb4,这个是真正的utf8,能够容纳所有的中文,其实一般情况下utf8就够用了。
为当前项目创建数据库用户
create user ly_user identified by '123';
grant all privileges on lyapi.* to 'ly_user'@'%';
flush privileges;
mysql -u luffy_user -pluffy
select user(); #luffy_user
配置数据库连接
在dev下配置数据库链接在项目主模块的 __init__.py
中导入pymysql
BASES = {
"default": {
"ENGINE": "django.db.backends.mysql",
"HOST": "127.0.0.1",
"PORT": 3306,
"USER": "luffy_user",
"PASSWORD": "123",
"NAME": "lyapi",
}
在项目主模块的 __init__.py
中导入pymysql
import pymysql
pymysql.install_as_MySQLdb()
数据库迁移指令
python manage.py makemigrations
python manage.py migrate
可能会遇到的一些问题
数据库版本检测导致的错误
数据库的版本检测代码注释掉
第二个错误也是因为数据库版本的默认编码导致,query返回的内容格式使用有误。
新增一行代码,把query查询结果转换格式为 bytes类型
前端项目
创建前端项目
vue create lyweb
前端初始化全局变量和全局方法
在src目录下创建settings.js站点开发配置文件
export default {
host:"http://127.0.0.1:8000",
}
在main.js中引入
import settings from "./settings"
Vue.prototype.$settings = settings; #将settings中的内容作为vue的属性,以后就不用每次都导包了
App.vue,全局css初始化代码
reset.css
body{
margin: 0;
padding: 0;
}
ul{
list-style: none;
padding: 0;
margin: 0;
}
li{
list-style: none;
}
/*.el-header{*/
/* width: 1200px;*/
/*}*/
input,select,textarea{
border: none;
outline: none;
}
a{
text-decoration: none;
color: #4a4a4a;
}
也可以把App.vue的style标签的css代码放到static外部目录下引用过来
main.js
import "../static/css/reset.css";
由于是vue create创建的项目,需要自己安装vue-router,然后创建router文件夹(index.js)
npm install vue-router@3.2.0 --save
index.js
import Vue from 'vue'
import Router from 'vue-router'
import Home from '@/components/HomePage'
Vue.use(Router)
export default new Router({
mode:'history',
routes: [
{
path: '/',
name: 'Home',
component: Home
}
]
})
main.js
import router from './router'
new Vue({
router,
render: h => h(App),
}).$mount('#app')
跨域CORS
在hosts文件添加如下两行,设置本地域名
127.0.0.1 www.lyapi.com
127.0.0.1 www.lyweb.com
使用www.lyapi.com访问出现如下错误时
在settings/dev.py的ALLOWED_HOSTS,设置允许访问
# 设置哪些客户端可以通过地址访问到后端
ALLOWED_HOSTS = [
'www.lyapi.com',
'www.lyweb.com',
]
后端-安装djangocorsheaders
pip install django-cors-headers==3.10.1
添加到中间件(中间件必须写在第一个)和installapps中
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware', #放在中间件的最上面,就是给响应头加上了一个响应头跨域
...
]
INSTALLED_APPS = (
...
'corsheaders',
...
)
添加白名单,确定一下哪些客户端可以跨域。
# CORS组的配置信息
CORS_ORIGIN_WHITELIST = (
#'www.luffycity.cn:8080', #如果这样写不行的话,就加上协议(http://www.luffycity.cn:8080,因为不同的corsheaders版本可能有不同的要求)
'http://www.lyweb.com:8080',
)
CORS_ALLOW_CREDENTIALS = False # 是否允许ajax跨域请求时携带cookie,False表示不用,我们后面也用不到cookie,所以关掉它就可以了,以防有人通过cookie来搞我们的网站
前端使用 axios就可以访问到后端提供给的数据接口,但是如果要附带cookie信息,前端还要设置一下。
前端引入axios插件并配置允许axios发送cookie信息[axios本身也不允许ajax发送cookie到后端]
npm install axios -S
在main.js中引用 axios插件
import axios from 'axios'; // 从node_modules目录中导入包
// 客户端配置是否允许ajax发送请求时附带cookie,false表示不允许
Vue.prototype.$axios = axios; // 把对象挂载vue中
axios.defaults.withCredentials = false;
出现的一些问题
vue eslint 报错 error “Component name “*****“ should always be multi-word”
这个错误是由于Vue.js的ESLint插件vue/multi-word-component-names在工程中强制执行的规则。这个规则要求组件的名称必须是多单词的,也就是说,它们应该由一个以上的大写字母或者连字符隔开。这是为了避免和现有的及未来的HTML元素冲突,因为HTML标签名称都是单个单词的。
安装xadmin
会出现三方件版本不适配的问题,在pypi上找相适应的版本
pip install https://codeload.github.com/sshwsfc/xadmin/zip/django2
xadmin有建立自己的数据库模型类,需要进行数据库迁移
python manage.py makemigrations
python manage.py migrate
xadmin数据库迁移出现的一些问题
admin报cannot import name ‘DEFAULT_FORMATS‘ from ‘import_export.admin‘/cannot import name ‘SKIP_ADMI
a、注释掉下面的命令
from import_export.admin import DEFAULT_FORMATS, SKIP_ADMIN_LOG, TMP_STORAGE_CLASS
b、增加下面两条
from import_export.formats.base_formats import DEFAULT_FORMATS
from import_export.admin import ImportMixin, ImportExportMixinBase
生成注册应用
python ..\..\manage.py startapp home
完成后run的时候会报找不到应用的错误,是因为他还是在根目录下那一级找的,而应用在apps下,在dev加上下面这个配置
因为子应用的位置发生了改变,所以为了原来子应用的注册写法,所以新增一个导包路径
import sys
sys.path.insert(0,os.path.join(BASE_DIR, 'apps'))
xadmin创建超级用户
python manage.py createsuperuser