永久配置安装源

为了加速模块的下载

1、文件管理器文件路径地址栏敲:%APPDATA% 回车,快速进入 C:\Users\电脑用户\AppData\Roaming 文件夹中
2、新建 pip 文件夹并在文件夹中新建 pip.ini 配置文件
3、新增 pip.ini 配置文件内容

配置内容

[global]
index-url = http://pypi.douban.com/simple
[install]
use-mirrors =true
mirrors =http://pypi.douban.com/simple/
trusted-host =pypi.douban.com

虚拟环境的搭建

优点

1、使不同应用开发环境相互独立
2、环境升级不影响其他应用,也不会影响全局的python环境
3、防止出现包管理混乱及包版本冲突

安装virtualenv           windows下(下面都是针对windows下)

# 建议使用pip3安装到python3环境下
pip3 install virtualenv
pip3 install virtualenvwrapper-win

配置环境变量

控制面板 => 系统和安全 => 系统 => 高级系统设置 => 环境变量 => 系统变量 => 点击新建 => 填入变量名与值
变量名:WORKON_HOME 变量值:自定义存放虚拟环境的绝对路径
eg: WORKON_HOME: D:\Virtualenvs 同步配置信息:
去向Python3的安装目录 => Scripts文件夹 => virtualenvwrapper.bat => 双击

使用virtualenv

# 在终端工作的命令

# 1、创建虚拟环境到配置的WORKON_HOME路径下
# 选取默认Python环境创建虚拟环境:
-- mkvirtualenv 虚拟环境名称
# 基于某Python环境创建虚拟环境:
-- mkvirtualenv -p python2.7 虚拟环境名称
-- mkvirtualenv -p python3.6 虚拟环境名称 # 2、查看已有的虚拟环境
-- workon # 3、使用某个虚拟环境
-- workon 虚拟环境名称 # 4、进入|退出 该虚拟环境的Python环境
-- python | exit() # 5、为虚拟环境安装模块
-- pip或pip3 install 模块名 # 6、退出当前虚拟环境
-- deactivate # 7、删除虚拟环境(删除当前虚拟环境要先退出)
-- rmvirtualenv 虚拟环境名称

后台Django项目创建

环境

为luffy项目创建一个虚拟环境
>: mkvirtualenv luffy workon luffy,进入虚拟环境,按照基础环境依赖安装模块
>: pip install django==2.0.7
>: pip install djangorestframework
>: pip install pymysql

创建项目   在luffy文件夹中创建一个luffyapi   django项目

前提:新建luffy文件夹
>: cd 建立的luffy文件夹
>: django-admin startproject luffyapi #生成一个luffyapi django项目 开发:用pycharm打开项目,并选择提前备好的虚拟环境

重构项目目录  (app设置在小luffyapi下面,原来的settings.py文件删除,使用settings文件夹,里面包含开发环境和上线环境的文件配置)

├── luffyapi
├── logs/ # 项目运行时/开发时日志目录 - 文件夹
├── manage.py # 脚本文件
├── luffyapi/ # 项目主应用,开发时的代码保存 - 包
├── apps/ # 开发者的代码保存目录,以模块[子应用]为目录保存 - 包
├── libs/ # 第三方类库的保存目录[第三方组件、模块] - 包
├── settings/ # 配置目录 - 包
├── dev.py # 项目开发时的本地配置
└── prod.py # 项目上线时的运行配置
├── urls.py # 总路由
└── utils/ # 多个模块[子应用]的公共函数类库[自己开发的组件]
└── scripts/ # 保存项目运营时的脚本文件 - 文件夹

 配置开发环境

1.修改 wsgi.py 与 manage.py 两个文件:  在开发阶段使用dev,上线之后使用prod
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'luffyapi.settings.dev') 2.将settings.py删除或改名,内容拷贝到settings/dev.py中 3.修改dev.py文件内容
LANGUAGE_CODE = 'zh-hans' #设置中文
TIME_ZONE = 'Asia/Shanghai'
USE_TZ = False 4.修改启动配置:见插图 5.在任何一个__init__.py文件中测试默认配置文件是否是dev.py文件
from django.conf import settings
print(settings)

第5步运行结果如果报错,对应的py文件也需要设置一下DJANGO_SETTINGS_MODULE=luffyapi.settings.dev

配置日志

在settings.dev配置文件中加入

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': {
# 实际开发建议使用WARNING
'level': 'INFO',
'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, # 是否让日志信息继续冒泡给其他的日志处理系统
},
}
}

环境变量设置  这步设置非常重要,没设置好后面项目不能使用(******)

# 环境变量操作:小luffyapiBASE_DIR与apps文件夹都要添加到环境变量
import sys
sys.path.insert(0, BASE_DIR)
APPS_DIR = os.path.join(BASE_DIR, 'apps')
sys.path.insert(1, APPS_DIR)

在写项目直接导入utils文件夹也不"错误提示"

封装logger

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': {
# 实际开发建议使用WARNING
'level': 'DEBUG',
'filters': ['require_debug_true'],
'class': 'logging.StreamHandler',
'formatter': 'simple'
},
'file': {
# 实际开发建议使用ERROR
'level': 'INFO',
'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/logging.py

import logging
logger = logging.getLogger('django')

封装项目异常处理

utils/exception.py   (自定义异常处理,在views视图可以使用)

from rest_framework.views import exception_handler as drf_exception_handler
from rest_framework.views import Response
from rest_framework import status
from utils.logging import logger
def exception_handler(exc, context):
response = drf_exception_handler(exc, context)
if response is None:
logger.error('%s - %s - %s' % (context['view'], context['request'].method, exc))
return Response({
'detail': '服务器错误'
}, status=status.HTTP_500_INTERNAL_SERVER_ERROR, exception=True)
return response

二次封装Response模块

utils/response.py      (自定义Response模块,在views视图导入APIResponse)

from rest_framework.response import Response

class APIResponse(Response):
def __init__(self, data_status=0, data_msg='ok', results=None, http_status=None, headers=None, exception=False, **kwargs):
data = {
'status': data_status,
'msg': data_msg,
}
if results is not None:
data['results'] = results
data.update(kwargs) super().__init__(data=data, status=http_status, headers=headers, exception=exception)

数据库配置(******)

创建数据库  (下面是在cmd中使用命令行方式创建,当然也可以使用navicat软件直接创建数据库luffy)

1.管理员连接数据库
>: mysql -uroot -proot 2.创建数据库
>: create database luffy default charset=utf8; 3.查看用户
>: select user,host,password from mysql.user;

为指定数据库配置指定账户  (如果不指定用户,就不用进行下面操作)

设置权限账号密码
# 授权账号命令: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?

在任意某个__init__.py文件下加入下面代码

import pymysql
pymysql.install_as_MySQLdb()

dev.py中配置数据库连接信息

DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'luffy',
'USER':'root',
'PASSWORD':'root'
}
}

Django2.x一些版本pymysql兼容问题(可能会出现的问题)

Django不采用2.0.7版本很可能出现以下问题,需要修改源代码

user应用User表

创建user模块

前提:在 luffy 虚拟环境下

1.终端从项目根目录进入apps目录
>: cd luffyapi & cd apps 2.创建user应用
>: python ../../manage.py startapp user

创建User表对应的model:user/model.py

from django.db import models
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
mobile = models.CharField(max_length=11, unique=True)
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

注册user模块,配置User表:dev.py     (必须先要把apps文件夹添加到环境变量里面)

INSTALLED_APPS = [
# ...
'user', #应用名
] # 自定义User表
AUTH_USER_MODEL = 'user.User'

配置media

media配置:dev.py    (配置图片存放的地址)

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

media目录配置    保存上传图片的文件夹需要先在media下创建,然后上传的图片会自动保存在创建的文件夹中

├── luffyapi
└── luffyapi/
└── media/
└── icon
└── default.png

配置路由

主路由:luffyapi/urls.py

from django.contrib import admin
from django.urls import path, re_path, include
from django.views.static import serve
from django.conf import settings
urlpatterns = [
path('admin/', admin.site.urls), path('user/', include('user.urls')), re_path('^media/(?P<path>.*)', serve, {'document_root': settings.MEDIA_ROOT})
]

子路由:user/urls.py

from django.urls import path, re_path
urlpatterns = [ ]

数据库迁移:在最外层目录输入:python manage.py makemigrations

然后输入:python manage.py migrate

前台搭建

搭建vue环境  (cmd中运行,如果已经搭建好了就不用再搭建了,直接从创建项目开始)

1.傻瓜式安装node:
官网下载:https://nodejs.org/zh-cn/ (需要下载就下载,下载过了就不用执行这句话了) 2.安装cnpm:
>: npm install -g cnpm --registry=https://registry.npm.taobao.org 3.安装vue最新脚手架:
>: cnpm install -g @vue/cli 注:如果2、3步报错,清除缓存后重新走2、3步
>: npm cache clean --force

创建项目

前提:新建luffy文件夹   (在创建django项目的时候已经创建好了luffy文件夹)
>: cd 建立的luffy文件夹
>: vue create luffycity

创建成功

 重构项目目录

├── luffycity
├── public/ # 项目共有资源
├── favicon.ico # 站点图标
└── index.html # 主页
├── src/ # 项目主应用,开发时的代码保存
├── assets/ # 前台静态资源总目录
├── css/ # 自定义css样式
└── global.css # 自定义全局样式
├── js/ # 自定义js样式
└── settings.js # 自定义配置文件
└── img/ # 前台图片资源
├── components/ # 小组件目录
├── views/ # 页面组件目录
├── App.vue # 根路由
├── main.js # 入口脚本文件
├── router
└── index.js # 路由脚本文件
store
└── index.js # 仓库脚本文件
├── vue.config.js # 项目配置文件
└── *.* # 其他配置文件

文件修订:目录中非配置文件的多余文件可以移除

App.vue   (多余的全部删除,只留这五行就行)

<template>
<div id="app">
<router-view/>
</div>
</template>

router/index.js

import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue' Vue.use(VueRouter); const routes = [
{
path: '/',
name: 'home',
component: Home
},
]; const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes
}); export default router

Home.vue

<template>
<div class="home">
</div>
</template> <script>
export default {
name: 'home',
components: {
},
}
</script>

全局配置:全局样式、配置文件

全局样式:assets/css/global.css

/* 声明全局样式和项目的初始化样式 */
body, h1, h2, h3, h4, 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; /* 合并边框 */
}

assets/js/settings.js

export default {
base_url: 'http://127.0.0.1:8000'
}

src/main.js

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store' Vue.config.productionTip = false; // 配置全局样式
import '@/assets/css/global.css' // 配置全局自定义设置
import settings from '@/assets/js/settings'
Vue.prototype.$settings = settings; // axios配置:cnpm install axios
import axios from 'axios'
Vue.prototype.$axios = axios; // cookies配置:cnpm install vue-cookies
import cookies from 'vue-cookies'
Vue.prototype.$cookies = cookies; // element-ui配置:cnpm install element-ui
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI); // bootstrap+jq配置:cnpm install jquery、cnpm install bootstrap@3
import 'bootstrap'
import 'bootstrap/dist/css/bootstrap.min.css' new Vue({
router,
store,
render: h => h(App)
}).$mount('#app');

前台配置

axios前后台交互

安装axios:在前端项目目录下的终端

cnpm install axios

配置:main.js

import axios from 'axios'
Vue.prototype.$axios = axios;

cookies操作

安装vue-cookies:前端项目目录下的终端

cnpm install vue-cookies

配置:main.js

import cookies from 'vue-cookies'
Vue.prototype.$cookies = cookies;

element_ui页面组件框架

安装element-ui:前端项目目录下的终端

cnpm install element-ui

配置:main.js

import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI);

bootstrap和jq的配置

安装bootstrap和jq:

cnpm install bootstrap@3
cnpm install jquery

配置bootstrap:main.js

import 'bootstrap'
import 'bootstrap/dist/css/bootstrap.min.css'

配置jquery:vue.config.js  (在根目录下创建)

const webpack = require("webpack");

module.exports = {
configureWebpack: {
plugins: [
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery",
"window.jQuery": "jquery",
"window.$": "jquery",
Popper: ["popper.js", "default"]
})
]
}
};

前端主页

图片准备        放在img文件夹中

页头组件:components/Header.vue  (小组件头部信息)

<template>
<div class="header-box">
<div class="header">
<div class="content">
<div class="logo full-left">
<router-link to="/"><img @click="jump('/')" src="@/assets/img/logo.svg" alt=""></router-link>
</div>
<ul class="nav full-left">
<li><span @click="jump('/course')" :class="this_nav=='/course'?'this':''">免费课</span></li>
<li><span @click="jump('/light-course')" :class="this_nav=='/light-course'?'this':''">轻课</span></li>
<li><span>学位课</span></li>
<li><span>题库</span></li>
<li><span>老男孩教育</span></li>
</ul>
<div class="login-bar full-right">
<div class="shop-cart full-left">
<img src="@/assets/img/cart.svg" alt="">
<span><router-link to="/cart">购物车</router-link></span>
</div>
<div class="login-box full-left">
<span>登录</span>
&nbsp;|&nbsp;
<span>注册</span>
</div>
</div>
</div>
</div>
</div>
</template> <script>
export default {
name: "Header",
data() {
return {
this_nav: "",
}
},
created() {
this.this_nav = localStorage.this_nav;
},
methods: {
jump(location) {
localStorage.this_nav = location;
// vue-router除了提供router-link标签跳转页面以外,还提供了js跳转的方式
this.$router.push(location);
}
}
}
</script> <style scoped>
.header-box {
height: 80px;
} .header {
width: 100%;
height: 80px;
box-shadow: 0 0.5px 0.5px 0 #c9c9c9;
position: fixed;
top: 0;
left: 0;
right: 0;
margin: auto;
z-index: 99;
background: #fff;
} .header .content {
max-width: 1200px;
width: 100%;
margin: 0 auto;
} .header .content .logo {
height: 80px;
line-height: 80px;
margin-right: 50px;
cursor: pointer;
} .header .content .logo img {
vertical-align: middle;
} .header .nav li {
float: left;
height: 80px;
line-height: 80px;
margin-right: 30px;
font-size: 16px;
color: #4a4a4a;
cursor: pointer;
} .header .nav li span {
padding-bottom: 16px;
padding-left: 5px;
padding-right: 5px;
} .header .nav li span a {
display: inline-block;
} .header .nav li .this {
color: #4a4a4a;
border-bottom: 4px solid #ffc210;
} .header .nav li:hover span {
color: #000;
} .header .login-bar {
height: 80px;
} .header .login-bar .shop-cart {
margin-right: 20px;
border-radius: 17px;
background: #f7f7f7;
cursor: pointer;
font-size: 14px;
height: 28px;
width: 88px;
margin-top: 30px;
line-height: 32px;
text-align: center;
} .header .login-bar .shop-cart:hover {
background: #f0f0f0;
} .header .login-bar .shop-cart img {
width: 15px;
margin-right: 4px;
margin-left: 6px;
} .header .login-bar .shop-cart span {
margin-right: 6px;
} .header .login-bar .login-box {
margin-top: 33px;
} .header .login-bar .login-box span {
color: #4a4a4a;
cursor: pointer;
} .header .login-bar .login-box span:hover {
color: #000000;
} .full-left {
float: left !important;
} .full-right {
float: right !important;
} .el-carousel__arrow {
width: 120px;
height: 120px;
} .el-checkbox__input.is-checked .el-checkbox__inner,
.el-checkbox__input.is-indeterminate .el-checkbox__inner {
background: #ffc210;
border-color: #ffc210;
border: none;
} .el-checkbox__inner:hover {
border-color: #9b9b9b;
} .el-checkbox__inner {
width: 16px;
height: 16px;
border: 1px solid #9b9b9b;
border-radius: 0;
} .el-checkbox__inner::after {
height: 9px;
width: 5px;
}
</style>

轮播图组件:components/Banner.vue

<template>
<el-carousel height="520px" :interval="" arrow="always">
<el-carousel-item>
<img src="@/assets/img/banner1.png" alt="">
</el-carousel-item>
<el-carousel-item>
<img src="@/assets/img/banner2.png" alt="">
</el-carousel-item>
<el-carousel-item>
<img src="@/assets/img/banner3.png" alt="">
</el-carousel-item>
</el-carousel>
</template>
<script>
export default {
name: "Banner",
}
</script> <style scoped>
.el-carousel__item h3 {
color: #475669;
font-size: 18px;
opacity: 0.75;
line-height: 300px;
margin: 0;
} .el-carousel__item:nth-child(2n) {
background-color: #99a9bf;
} .el-carousel__item:nth-child(2n+1) {
background-color: #d3dce6;
}
.el-carousel__item img {
text-align: center;
height: 520px;
margin: 0 auto;
display: block;
}
</style>

页脚组件:components/Footer.vue

<template>
<div class="footer">
<ul>
<li>关于我们</li>
<li>联系我们</li>
<li>商务合作</li>
<li>帮助中心</li>
<li>意见反馈</li>
<li>新手指南</li>
</ul>
<p>Copyright © luffycity.com版权所有 | 京ICP备17072161号-1</p>
</div>
</template> <script>
export default {
name: "Footer"
}
</script> <style scoped>
.footer {
width: 100%;
height: 128px;
background: #25292e;
color: #fff;
} .footer ul {
margin: 0 auto 16px;
padding-top: 38px;
width: 810px;
} .footer ul li {
float: left;
width: 112px;
margin: 0 10px;
text-align: center;
font-size: 14px;
} .footer ul::after {
content: "";
display: block;
clear: both;
} .footer p {
text-align: center;
font-size: 12px;
}
</style>

主页组件:views/Home.vue

<template>
<div class="home">
     #小组件页面导入
<Header />
<Banner />
<Footer />
</div>
</template> <script>
  #导入小组件
import Header from '@/components/Header'
import Banner from '@/components/Banner'
import Footer from '@/components/Footer' export default {
name: 'home',
components: {
       #小组件注册
Header,
Banner,
Footer
},
}
</script>

后台主页模块设计

创建home应用  (在apps文件夹下面执行python ../../manage.py startapp home)

前提:在 luffy 虚拟环境下

1.终端从项目根目录进入apps目录
>: cd luffyapi & cd apps 2.创建app
>: python ../../manage.py startapp home

路由分发

主路由:luffyapi/urls.py

from django.urls import path, re_path, include
urlpatterns = [
# ...
path('user/', include('home.urls')),
# ...
]

子路由:home/urls.py

from django.urls import path, re_path
urlpatterns = [ ]

Banner数据表model设计

utils/models.py   (创建一个基类,所有的model都可以继承这三个字段)

from django.db import models

class BaseModel(models.Model):
orders = models.IntegerField(verbose_name='显示顺序')
is_show = models.BooleanField(verbose_name="是否上架", default=False)
is_delete = models.BooleanField(verbose_name="逻辑删除", default=False) class Meta:
abstract = True

home/models.py

from django.db import models
from utils.model import BaseModel class Banner(BaseModel):
image = models.ImageField(upload_to='banner', verbose_name='轮播图', null=True, blank=True) #需要在media文件夹下创建banner文件夹,会把上传图片自动放入该文件夹中
name = models.CharField(max_length=150, verbose_name='轮播图名称')
note = models.CharField(max_length=150, verbose_name='备注信息')
link = models.CharField(max_length=150, verbose_name='轮播图广告地址') class Meta:
db_table = 'luffy_banner'
verbose_name = '轮播图'
verbose_name_plural = verbose_name def __str__(self):
return self.name

注册模块:dev.py

INSTALLED_APPS = [
# ...
'rest_framework',
'home',
]

数据库迁移:在大luffyapi路径下的终端

>: python manage.py makemigrations
>: python manage.py migrate

设计Banner数据接口

home/serializers.py

from rest_framework.serializers import ModelSerializer
from . import models class BannerModelSerializer(ModelSerializer):
class Meta:
model = models.Banner
fields = ['name', 'note', 'image', 'link']

home/views.py

from rest_framework.generics import ListAPIView
from utils.response import APIResponse
from . import models,serializers class BannerListAPIView(ListAPIView):
queryset = models.Banner.objects.filter(is_delete=False,is_show=True).order_by('-orders')
serializer_class = serializers.BannerModelSerializer

home/urls.py

from django.urls import path, re_path
from . import views
urlpatterns = [
path('banners/', views.BannerListAPIView.as_view())
]

在postman中测试接口:

http://127.0.0.1:8000/home/banners/

分离的前后台交互

后台处理跨域问题

安装插件

>: pip install django-cors-headers

插件参考地址:https://github.com/ottoyiu/django-cors-headers/

项目配置:dev.py

# 注册app
INSTALLED_APPS = [
...
'corsheaders'
] # 添加中间件
MIDDLEWARE = [
...
'corsheaders.middleware.CorsMiddleware'
] # 允许跨域源
CORS_ORIGIN_ALLOW_ALL = True

前台请求Banner数据

修订Banner.vue

<template>
<el-carousel height="520px" :interval="" arrow="always">
     #渲染后台数据
<el-carousel-item :v-for="banner in banner_list" :key="banner.name">
<a :href="banner_link">
<img :src="banner.img" alt="" :title="banner.note">
</a>
</el-carousel-item> </el-carousel>
</template>
<script>
export default {
name: "Banner",
data(){
return {
banner_list:[]
}
},
//钩子函数,当页面运行结束时执行
created(){
//请求后台数据,类似于ajax
this.$axios({
url:this.$settings.base_url+'/home/banners/',
methods:'get',
}).then(response => { //function () 可以用response =>
this.banner_list = response.data; //返回给前台的数据
}).catch(errors=>{
window.console.log(errors) //捕获异常
})
}
}
</script> <style scoped>
.el-carousel__item h3 {
color: #475669;
font-size: 18px;
opacity: 0.75;
line-height: 300px;
margin: 0;
} .el-carousel__item:nth-child(2n) {
background-color: #99a9bf;
} .el-carousel__item:nth-child(2n+1) {
background-color: #d3dce6;
}
.el-carousel__item img {
text-align: center;
height: 520px;
margin: 0 auto;
display: block;
}
</style>

使用admin添加数据

在后台应用的admin.py

from django.contrib import admin

from . import models

admin.site.register(models.Banner)

创建超级用户登录账号

页面访问admin页面,添加数据

DRF+Vue项目(一)——项目架构的更多相关文章

  1. 中小研发团队架构实践之生产环境诊断工具WinDbg 三分钟学会.NET微服务之Polly 使用.Net Core+IView+Vue集成上传图片功能 Fiddler原理~知多少? ABP框架(asp.net core 2.X+Vue)模板项目学习之路(一) C#程序中设置全局代理(Global Proxy) WCF 4.0 使用说明 如何在IIS上发布,并能正常访问

    中小研发团队架构实践之生产环境诊断工具WinDbg 生产环境偶尔会出现一些异常问题,WinDbg或GDB是解决此类问题的利器.调试工具WinDbg如同医生的听诊器,是系统生病时做问题诊断的逆向分析工具 ...

  2. 深入浅出的webpack4构建工具--webpack4+vue+route+vuex项目构建(十七)

    阅读目录 一:vue传值方式有哪些? 二:理解使用Vuex 三:webpack4+vue+route+vuex 项目架构 回到顶部 一:vue传值方式有哪些? 在vue项目开发过程中,经常会使用组件来 ...

  3. Java 18套JAVA企业级大型项目实战分布式架构高并发高可用微服务电商项目实战架构

    Java 开发环境:idea https://www.jianshu.com/p/7a824fea1ce7 从无到有构建大型电商微服务架构三个阶段SpringBoot+SpringCloud+Solr ...

  4. 一个word合并项目的分布式架构设计

    一个word合并项目的分布式架构设计 项目背景与问题起源 我们要给一个客户做word生成报告以及报告合并的工作,要合并的报告非常多,而且每个报告也比较大,一个多的报告大概有200页以上.我们用c#操作 ...

  5. Vue实战Vue-cli项目构建(Vue+webpack系列之一)

    用Vue比较长一段时间了,大大小小做了一些项目,最近想总结一下知识点,出一个Vue+webpack系列,先从项目构建说起--vue-cli. 由于是Vue+webpack这里就不赘述git那些东西,默 ...

  6. VUE学习笔记之vue cli 构建项目

    一.环境搭建: 1.安装node.js 从node.js官网下载并安装node,安装过程很简单,一路"下一步"就可以了.安装完成之后,打开命令行工具(win+r,然后输入cmd), ...

  7. Vue常用开源项目汇总

    前言:Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架.与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用.Vue 的核心库只关注视图层,不仅易于上手,还 ...

  8. Vue练手项目(包含typescript版本)

    本项目的git仓库https://github.com/lznism/xiachufang-vue 对应的使用typescript实现的版本地址https://github.com/lznism/xi ...

  9. Vue + WebApi 小项目:构造自己的在线 Markdown 笔记本应用

    Vue + WebApi 小项目:构造自己的在线 Markdown 笔记本应用 目录 概要 知识点 完整示例图 代码与资源文件 流程步骤 概要 基于 MVP 最小可行性产品设计理念,我们先完成一个可以 ...

随机推荐

  1. python TypeError: unsupported operand type(s) for +: 'geoprocessing value object' and 'str'

    TypeError: unsupported operand type(s) for +: 'geoprocessing value object' and 'str' if self.params[ ...

  2. 屏幕录制 -- web前端

    前端使用html5.ffmpeg实现录屏摄像等功能 https://tong-h.github.io/2018/11/06/streamcapture/ JSCapture – 基于 HTML5 实现 ...

  3. Nginx流控

    流量限制(rate-limiting),是Nginx中一个非常实用,却经常被错误理解和错误配置的功能.我们可以用来限制用户在给定时间内HTTP请求的数量.请求,可以是一个简单网站首页的GET请求,也可 ...

  4. JS 数组对象的某一项抽离出来放在外面

    数组类型: shamDeviceData: [ { "projectKey":"5555", "productKey":"5555 ...

  5. 写了一个具有future接口的rust测试代码

    写了一个具有future接口的rust测试代码 但没有实现future功能,内部是直接求值 struct Future<T> { t: T, } impl<T> Future& ...

  6. linux内核在挂载ramdisk的过程中报错"RAMDISK: incomplete write (10739 != 32768)"如何处理?

    1. 原因 ramdisk大小不够 2. 解决方法 在启动变量bootargs中添加参数"ramdisk_size=10000000"即可

  7. shell脚本将gbk文件转化为utf-8

    使用注意项: 原来文件格式gbk的,否则可能出现utf-8转utf-8乱码. #!/bin/bash function gbk2utf(){ file="$1" echo &quo ...

  8. jsoup获取文章内容

    jsoup爬取文章内容 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws Se ...

  9. 前端速查手册——Note

    目录 自定义弹框(模块框) HTML5新增标签 HTML5新增属性 自定义弹框(模块框) HTML <div style="display:none" id="mo ...

  10. ES6深入浅出-12 ES6新增的API(下)-1.录屏

    String.includes es5里面判断字符串是否存在的方法 search searcg的厉害之处是可以使用正则 match正则的方式 repeat -1遍,就不合法 startsWith 判断 ...