4.6ロギング設定
さらに、設定/ dev.pyファイルを、次のとおりです。
# 日志配置
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': {
'level': 'DEBUG',
'filters': ['require_debug_true'],
'class': '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'
},
},
# 日志对象
'loggers': {
'luffy': {
'handlers': ['console', 'file'],
'propagate': True, # 是否让日志信息继续冒泡给其他的日志处理系统
},
}
}
4.5例外処理
新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('luffy')
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)
return response
追加する設定/ dev.py設定ファイル
REST_FRAMEWORK = {
# 异常处理
'EXCEPTION_HANDLER': 'luffy.utils.exceptions.custom_exception_handler',
}
4.7データベースの作成
create database luffycity default charset=utf8;
現在のプロジェクトのためのデータベースユーザーを作成し、[ユーザーはこのデータベースを見ることができます]
create user luffy_user identified by 'luffy';
grant all privileges on luffycity.* to 'luffy_user'@'%';
flush privileges;
4.8データベース接続の構成
設定/ dev.pyファイルを開き、設定
DATABASES = {
"default": {
"ENGINE": "django.db.backends.mysql",
"HOST": "127.0.0.1",
"PORT": 3306,
"USER": "luffy_user",
"PASSWORD": "luffy",
"NAME": "luffycity",
}
}
メインプログラムモジュールで__init__.py
pymysqlで導入
import pymysql
pymysql.install_as_MySQLdb()
調整誤差
データベースのバージョンの検出誤差が発生します
バージョン検出データベース・コードコメントアウト。、
デフォルトでは、原因のデータベースのバージョンを符号化するため、2番目のエラーがあり、クエリは、コンテンツのフォーマットが間違って返します。
コードの行を追加し、クエリがフォーマットバイト型になり
フロントエンドを構築するプロジェクト
5.1プロジェクトディレクトリを作成します
cd 项目目录
vue init webpack lufei_pc
例えば、私は、あなたが次の操作を行うことができますデスクトップの下で〜/デスクトップディレクトリにプロジェクトを保存します:
cd ~/Desktop
vue init webpack lufei_pc
プロジェクトをビルドする際に必要な、我々は対応するオプションの効果を選択します。
上記のヒントによると、私たちは、優れたプロジェクトVUEを構築、テストサーバーを実行する必要があります。
開いているプロジェクトには、結果を表示するために、端末プロジェクトVUEのpycharmで実行されています。
npm run dev
次に、我々はあなたがVUEを実行している複数のプロジェクトを持っている場合、8080ポートが占有されている(端末表示に対応するエフェクトに合わせてプロジェクトへのアクセスに対処する、サーバーは自動的にポートを変更しますので、実際にアクセスするには、運転中に自分のアドレスを参照してください。)
訪問します。http:// localost:8080。効果:
また、当社のフロントエンドプロジェクトのGitのソースコード管理を置くことができます
5.2フロントエンドプロジェクトの初期化
クリアデフォルトのスタイルデフォルトのHelloWorldのコンポーネントとAPP.vueで
次に、効果、および一枚の紙を見ることができます -
5.3インストールVUE-ルータのルーティング
5.3.1ダウンロードのルーティングコンポーネント
npm i vue-router -S
結果の実装:
5.3.2ルーティングの設定
5.3.2.1ルート・オブジェクトの初期化
srcディレクトリの下にルータのルーティングディレクトリを作成し、ルータのルーティングindex.jsディレクトリにファイルを作成
ファイルルーティングindex.jsは、ルートオブジェクトを初期化するコードを書きます。
import Vue from "vue"
import Router from "vue-router"
// 这里导入可以让让用户访问的组件
Vue.use(Router);
export default new Router({
// 设置路由模式为‘history’,去掉默认的#
mode: "history",
routes:[
// 路由列表
]
})
5.3.2.2登録ルーティング情報
Main.js開いているファイルは、ルータのオブジェクトがVUEコードに登録されています。
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from './routers/index';
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
components: { App },
template: '<App/>'
});
ビュー内のルートに対応5.3.2.3表示内容
在App.vue组件中,添加显示路由对应的内容。
代码:
<template>
<div id="app">
<router-view/>
</div>
</template>
<style>
</style>
5.3.2.4 创建并提供前端首页的组件
routers/index.js
// import Vue from "vue"
// import Router from "vue-router"
//
//
// // 这里导入可以让让用户访问的组件
import Home from "../components/Home"
// Vue.use(Router);
//
// export default new Router({
// // 设置路由模式为‘history’,去掉默认的#
// mode: "history",
// routes:[
// // 路由列表
{
name:"Home",
path:"/",
component:Home,
},
{
name:"Home",
path:"/home",
component:Home,
},
]
// })
创建Home组件
components/Home.vue
<template>
<div id="home">
前端首页
</div>
</template>
<style scoped>
</style>
5.4 前端初始化全局变量和全局方法
在src目录下创建settings.js站点开发配置文件:
export default {
Host:"http://127.0.0.1",
}
在main.js中引入
// // The Vue build version to load with the `import` command
// // (runtime-only or standalone) has been set in webpack.base.conf with an alias.
// import Vue from 'vue'
// import App from './App'
// import router from './routers/index';
import settings from "./settings"
// Vue.config.productionTip = false;
Vue.prototype.$settings = settings;
//
// /* eslint-disable no-new */
// new Vue({
// el: '#app',
// router,
// components: { App },
// template: '<App/>'
// });
5.5 引入ElementUI
npm i element-ui -S
上面的命令等同于
npm install element-ui --save
执行命令效果:
5.5.1 配置ElementUI到项目中
在main.js中导入ElementUI,并调用。
代码:
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
// import Vue from 'vue'
// import App from './App'
// import router from './routers/index';
// 开发配置文件
// import settings from "./settings"
// Vue.prototype.$settings = settings;
// elementUI 导入
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
// 调用插件
Vue.use(ElementUI);
// Vue.config.productionTip = false;
/* eslint-disable no-new */
// new Vue({
// el: '#app',
// router,
// components: { App },
// template: '<App/>'
// });
效果:
成功引入了ElementUI以后,接下来我们就可以开始进入前端页面开发,首先是首页。
接下来我们把之前完成的首页,直接拿过来使用[注意除了组件以外,还有静态文件也需要拿过来,包括App.vue里面的公共样式],并运行项目。
App.vue,全局css初始化代码
<style>
body,h1,h2,h3,h4,h5,ul,p{
padding: 0;
margin:0;
font-weight: normal;
}
body{
margin-top: 80px;
}
a{
text-decoration: none;
color: #4a4a4a;
}
a:hover{
color: #000;
}
ul{
list-style: none;
}
img{
width: 100%;
}
.header .el-menu li .el-submenu__title{
height: 26px!important;
line-height: 26px!important;
}
.el-menu--popup{
min-width: 140px;
}
.el-checkbox__inner{
width:16px;
height: 16px;
border: 1px solid #999;
}
.el-checkbox__inner:after{
width: 6px;
height: 8px;
}
.el-form-item__content{
margin-left:0px!important;
width: 120px;
}
</style>
Home.vue中添加代码:
<template>
<div id="home">
<Header/>
<Banner/>
<Footer/>
</div>
</template>
<style scoped>
</style>
components/common/Header.vue
<template>
<div class="header">
<el-container>
<el-header>
<el-row>
<el-col class="logo" :span="3">
<a href="/">
<img src="@/assets/head-logo.svg" alt="">
</a>
</el-col>
<el-col class="nav" :span="16">
<el-row>
<el-col :span="3"><router-link class="current" to="/course">免费课</router-link></el-col>
<el-col :span="3"><router-link to="/">轻课</router-link></el-col>
<el-col :span="3"><router-link to="/">学位课</router-link></el-col>
<el-col :span="3"><router-link to="/">题库</router-link></el-col>
<el-col :span="3"><router-link to="/">教育</router-link></el-col>
</el-row>
</el-col>
<el-col class="login-bar" :span="5">
<el-row v-if="token">
<el-col class="cart-ico" :span="9">
<router-link to="">
<b class="goods-number">0</b>
<img class="cart-icon" src="@/assets/cart.svg" alt="">
<span><router-link to="/cart">购物车</router-link></span>
</router-link>
</el-col>
<el-col class="study" :span="8" :offset="2"><router-link to="">学习中心</router-link></el-col>
<el-col class="member" :span="5">
<el-menu class="el-menu-demo" mode="horizontal">
<el-submenu index="2">
<template slot="title"><router-link to=""><img src="@/assets/[email protected]" alt=""></router-link></template>
<el-menu-item index="2-1">我的账户</el-menu-item>
<el-menu-item index="2-2">我的订单</el-menu-item>
<el-menu-item index="2-3">我的优惠卷</el-menu-item>
<el-menu-item index="2-3">退出登录</el-menu-item>
</el-submenu>
</el-menu>
</el-col>
</el-row>
<el-row v-else>
<el-col class="cart-ico" :span="9">
<router-link to="">
<img class="cart-icon" src="@/assets/cart.svg" alt="">
<span><router-link to="/cart">购物车</router-link></span>
</router-link>
</el-col>
<el-col :span="10" :offset="5">
<span class="register">
<router-link to="/login">登录</router-link>
|
<router-link to="/register">注册</router-link>
</span>
</el-col>
</el-row>
</el-col>
</el-row>
</el-header>
</el-container>
</div>
</template>
<style scoped>
.header{
top:0;
left:0;
right:0;
margin: auto;
background-color: #fff;
height: 80px;
z-index: 1000;
position: fixed;
box-shadow: 0 0.5px 0.5px 0 #c9c9c9;
}
.header .el-container{
width: 1200px;
margin: 0 auto;
}
.el-header{
height: 80px!important;
padding:0;
}
.logo{
}
.logo img{
padding-top: 22px;
}
.nav{
margin-top: 22px;
}
.nav .el-col a{
display: inline-block;
text-align: center;
padding-bottom: 16px;
padding-left: 5px;
padding-right: 5px;
position: relative;
font-size: 16px;
margin-left: 20px;
}
.nav .el-col .current{
color: #4a4a4a;
border-bottom: 4px solid #ffc210;
}
.login-bar{
margin-top: 22px;
}
.cart-ico{
position: relative;
border-radius: 17px;
}
.cart-ico:hover{
background: #f0f0f0;
}
.goods-number{
width: 16px;
height: 16px;
line-height: 17px;
font-size: 12px;
color: #fff;
text-align: center;
background: #fa6240;
border-radius: 50%;
transform: scale(.8);
position: absolute;
left: 16px;
top: -1px;
}
.cart-icon{
width: 15px;
height: auto;
margin-left: 6px;
}
.cart-ico span{
margin-left: 12px;
}
.member img{
width: 26px;
height: 26px;
border-radius: 50%;
display: inline-block;
}
.member img:hover{
border: 1px solid yellow;
}
</style>
components/common/Bannner.vue
<template>
<div class="banner">
<el-carousel trigger="click" height="473px">
<el-carousel-item v-for="banner in banner_list">
<a :href="banner.link"><img width="100%" :src="banner.img" alt=""></a>
</el-carousel-item>
</el-carousel>
</div>
</template>
<style>
.el-carousel__arrow{
width: 100px!important;
height: 100px!important;
}
.el-icon-arrow-left{
font-size: 35px;
margin-left: 50px;
}
.el-carousel__arrow--left{
left: -50px;
}
</style>
components/common/Footer.vue
<template>
<div class="footer">
<el-container>
<el-row>
<el-col :span="4"><router-link to="">关于我们</router-link></el-col>
<el-col :span="4"><router-link to="">联系我们</router-link></el-col>
<el-col :span="4"><router-link to="">商务合作</router-link></el-col>
<el-col :span="4"><router-link to="">帮助中心</router-link></el-col>
<el-col :span="4"><router-link to="">意见反馈</router-link></el-col>
<el-col :span="4"><router-link to="">新手指南</router-link></el-col>
<el-col :span="24"><p class="copyright">Copyright © luffycity.com版权所有 | 京ICP备17072161号-1</p></el-col>
</el-row>
</el-container>
</div>
</template>
<style scoped>
.footer{
width: 100%;
height: 128px;
background: #25292e;
}
.footer .el-container{
width: 1200px;
margin: auto;
}
.footer .el-row {
align-items: center;
padding: 0 200px;
padding-bottom: 15px;
width: 100%;
margin-top: 38px;
}
.footer .el-row a{
color: #fff;
font-size: 14px;
}
.footer .el-row .copyright{
text-align: center;
color: #fff;
font-size: 14px;
}
</style>
也可以把App.vue的style标签的css代码放到static外部目录下引用过来
main.js
import "../static/css/reset.css";
reset.css
body,h1,h2,h3,h4,h5,ul,p{
padding: 0;
margin:0;
font-weight: normal;
}
body{
margin-top: 80px;
}
a{
text-decoration: none;
color: #4a4a4a;
}
a:hover{
color: #000;
}
ul{
list-style: none;
}
img{
width: 100%;
}
.header .el-menu li .el-submenu__title{
height: 26px!important;
line-height: 26px!important;
}
.el-menu--popup{
min-width: 140px;
}
.el-checkbox__inner{
width:16px;
height: 16px;
border: 1px solid #999;
}
.el-checkbox__inner:after{
width: 6px;
height: 8px;
}
.el-form-item__content{
margin-left:0px!important;
width: 120px;
}
6. 跨域CORS
我们现在为前端和后端分别设置两个不同的域名:
位置 | 域名 |
---|---|
前端 | www.luffycity.cn |
后端 | api.luffycity.cn |
编辑/etc/hosts
文件,可以设置本地域名
sudo vim /etc/hosts
在文件中增加两条信息
127.0.0.1 localhost
127.0.0.1 api.luffycity.cn
127.0.0.1 www.luffycity.cn
通过浏览器访问前端vue项目,会出现nginx的欢迎页面,主要因为我们当前项目已经有一个nginx监听了80端口,所以访问www.luffycity.cn网址时,会自动被转发到127.0.0.1本机,因为没有网址默认端口是80端口,所以被nginx进行处理了当前请求,因此我们暂时先把nginx关闭先。
# 查找nginx的进程
ps -ef|grep nginx
# 关闭进程
sudo kill -9 nginx进程号
关闭了nginx以后,访问www.luffy.cirty.cn网址,效果:
上面并不是错误,而是没人监听了这个地址和端口了,解决方法:
暂停运行前端项目,并修改配置文件config/index.js
host: 'www.luffycity.cn', // can be overwritten by process.env.HOST
port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined
autoOpenBrowser: true,
保存修改信息,并重启项目
ブラウザアクセスを通じてDRFプロジェクト、次のエラーメッセージ
ALLOWED_HOSTSによって設定/ dev.pyは、アクセスを許可するように設けられています
# 设置哪些客户端可以通过地址访问到后端
ALLOWED_HOSTS = [
'api.luffycity.cn',
]
api.luffycity.cn:8000を使用した場合、ユーザーがアクセスすることを許可
1. 修改pycharm的manage.py的配置参数
さて、フロントとバックエンド・ポイントが異なるドメイン名で、我々は、クロスドメインアクセスのためのバックエンドサポートに追加する必要があります
それ以外の場合は、フロントエンド、バックエンドのデータAPI要求を提供することができませんでしaxios使用することはできません、我々は、クロスドメインアクセスのためのバックエンドサポートを解決するためにCORSを使用しています。
ジャンゴ・CORS-ヘッダの拡張を使用して
在 Response(headers={"Access-Control-Allow-Origin":'客户端地址/*'})
ドキュメンテーションます。https://github.com/ottoyiu/django-cors-headers/
インストール
pip install django-cors-headers
アプリケーションの追加
INSTALLED_APPS = (
...
'corsheaders',
...
)
中間層は、セット[A]の位置に書き込まれなければなりません
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware',
...
]
ホワイトリストを追加
# CORS组的配置信息
CORS_ORIGIN_WHITELIST = (
'www.luffycity.cn:8080'
)
CORS_ALLOW_CREDENTIALS = True # 允许ajax跨域请求时携带cookie
上記の手順を完了し、我々は、バックエンドによってアクセスAJAXを使用して、フロントエンドにデータを提供することができます。
Axiosフロントエンドは、バックエンドを提供するために、データ・インタフェースにアクセスするには、しかし、あなたがクッキー情報を添付したい場合は、だけでなく、フロントエンドの外観を設定します。
【Axios自体がクッキー後部AJAXを送信することを許可されていない遠位端を導入し、プラグAxios Axiosは、クッキー情報を送信可能にするように構成
npm i axios -S
基準axiosプラグインmain.jsで
import axios from 'axios'; // 从node_modules目录中导入包
// 允许ajax发送请求时附带cookie
axios.defaults.withCredentials = true;
Vue.prototype.$axios = axios; // 把对象挂载vue中