前台主页搭建

vue前端组件开发

components/Homeviwe.vue

<template>
<div class="home">
<Header></Header>
<Banner></Banner> <!-- 推荐课程-->
<div class="course">
<el-row>
<el-col :span="6" v-for="(o, index) in 8" :key="o">
<el-card :body-style="{ padding: '0px' }" class="course_card">
<img src="https://tva1.sinaimg.cn/large/e6c9d24egy1h1g0zd133mj20l20a875i.jpg" class="image">
<div style="padding: 14px;">
<span>推荐的课程</span>
<div class="bottom clearfix">
<time class="time">价格:100元</time>
<el-button type="text" class="button">查看详情</el-button>
</div>
</div>
</el-card>
</el-col>
</el-row>
</div>
<img src="https://tva1.sinaimg.cn/large/e6c9d24egy1h1g112oiclj224l0u0jxl.jpg" alt="" height="500px"
width="100%"> <Footer></Footer>
</div>
</template> <script>
import Footer from "@/components/Footer";
import Header from "@/components/Header";
import Banner from "@/components/Banner"; export default {
name: 'HomeView',
data() {
return {}
},
components: {
Footer,
Header,
Banner
}
}
</script> <style scoped>
.time {
font-size: 13px;
color: #999;
} .bottom {
margin-top: 13px;
line-height: 12px;
} .button {
padding: 0;
float: right;
} .image {
width: 100%;
display: block;
} .clearfix:before,
.clearfix:after {
display: table;
content: "";
} .clearfix:after {
clear: both
} .course {
margin-left: 20px;
margin-right: 20px;
} .course_card {
margin: 50px;
}
</style>

components/Banner.vue

<template>
<div class="banner">
<el-carousel :interval="5000" arrow="always" height="400px">
<el-carousel-item v-for="item in 4" :key="item">
<img src="../assets/img/banner1.png" alt="">
</el-carousel-item>
</el-carousel>
</div>
</template> <script>
export default {
name: "Banner"
}
</script> <style scoped> el-carousel-item {
height: 400px;
min-width: 1200px;
} .el-carousel__item img {
height: 400px;
margin-left: calc(50% - 1920px / 2);
}
</style>

components/Header.vue

<template>
<div class="header">
<div class="slogan">
<p>路飞学城 | 帮助有志向的年轻人通过努力学习获得体面的工作和生活</p>
</div>
<div class="nav">
<ul class="left-part">
<li class="logo">
<router-link to="/">
<img src="../assets/img/head-logo.svg" alt="">
</router-link>
</li>
<li class="ele">
<span @click="goPage('/free-course')" :class="{active: url_path === '/free-course'}">免费课</span>
</li>
<li class="ele">
<span @click="goPage('/actual-course')" :class="{active: url_path === '/actual-course'}">实战课</span>
</li>
<li class="ele">
<span @click="goPage('/light-course')" :class="{active: url_path === '/light-course'}">轻课</span>
</li>
</ul> <div class="right-part">
<div>
<span>登录</span>
<span class="line">|</span>
<span>注册</span>
</div>
</div>
</div>
</div> </template> <script> export default {
name: "Header",
data() {
return {
url_path: sessionStorage.url_path || '/',
}
},
methods: {
goPage(url_path) {
// 已经是当前路由就没有必要重新跳转
if (this.url_path !== url_path) {
this.$router.push(url_path);
}
sessionStorage.url_path = url_path;
},
},
created() {
sessionStorage.url_path = this.$route.path;
this.url_path = this.$route.path;
}
}
</script> <style scoped>
.header {
background-color: white;
box-shadow: 0 0 5px 0 #aaa;
} .header:after {
content: "";
display: block;
clear: both;
} .slogan {
background-color: #eee;
height: 40px;
} .slogan p {
width: 1200px;
margin: 0 auto;
color: #aaa;
font-size: 13px;
line-height: 40px;
} .nav {
background-color: white;
user-select: none;
width: 1200px;
margin: 0 auto; } .nav ul {
padding: 15px 0;
float: left;
} .nav ul:after {
clear: both;
content: '';
display: block;
} .nav ul li {
float: left;
} .logo {
margin-right: 20px;
} .ele {
margin: 0 20px;
} .ele span {
display: block;
font: 15px/36px '微软雅黑';
border-bottom: 2px solid transparent;
cursor: pointer;
} .ele span:hover {
border-bottom-color: orange;
} .ele span.active {
color: orange;
border-bottom-color: orange;
} .right-part {
float: right;
} .right-part .line {
margin: 0 10px;
} .right-part span {
line-height: 68px;
cursor: pointer;
}
</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>

后台主页轮播图接口

创建home应用

startapp home

表设计

utils/model.py/BaseModel

from django.db import models
# 5个公共字段
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 # 表示它是虚拟的,不在数据库中生成表,它只用来做继承

迁移数据,创建超级用户

命令

# python manage.py makemigrations  ---》如果没有变化,是app没注册
# python manage.py migrate
# python manage.py createsuperuser --->创建个用户

pycharm快捷

引入simpleui,录入数据

# 下载
pip install django-simpleui # dev.py注册app
INSTALLED_APPS = [
'simpleui',
...
] # 在home/admin中写
from django.contrib import admin
from .models import Banner @admin.register(Banner)
class BannerAdmin(admin.ModelAdmin):
list_display = ('id', 'title', 'link','is_show', 'is_delete') # 增加自定义按钮
actions = ['make_copy']
def make_copy(self, request, queryset):
# 选中一些数据,点击 【自定义按钮】 触发方法执行,传入你选中 queryset
# 保存,删除
print(queryset)
make_copy.short_description = '自定义按钮'

轮播图接口格式

格式如下,可以使用自定制的APIResponse

{code:100,msg:成功,result:[{img:地址,link:跳转地址,orders:顺序,title:名字},{img:地址,link:跳转地址,orders:顺序,title:名字}]}

轮播图接口实现

总路由:urls.py

urlpatterns = [
path('admin/', admin.site.urls),
path('api/v1/home/', include('home.urls')), # http://127.0.0.1:8000/api/v1/home/banner/
]

home路由:urls.py

from django.urls import path, include
from rest_framework.routers import SimpleRouter
from .views import BannerView router = SimpleRouter()
router.register('banner', BannerView, 'banner')
urlpatterns = [
path('', include(router.urls)), ]

视图类

from .models import Banner
from .serializer import BannerSerializer
from utils.response import APIResponse
from rest_framework.viewsets import GenericViewSet
from rest_framework.mixins import ListModelMixin
class BannerView(GenericViewSet,ListModelMixin):
# 获取所有接口-list,自动生成路由
queryset = Banner.objects.filter(is_delete=False,is_show=True).order_by('orders')
serializer_class =BannerSerializer def list(self, request, *args, **kwargs): # 重写list
res=super().list(request, *args, **kwargs)
return APIResponse(result=res.data)

序列化类

from rest_framework import serializers
from .models import Banner class BannerSerializer(serializers.ModelSerializer):
class Meta:
model = Banner
fields = ['title', 'image', 'link', 'orders']


处理跨域请求

同源策略

同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现

请求的url地址,必须与浏览器上的url地址处于同域上,也就是域名,端口,协议相同,否则,加载回来的数据就会禁止,比如:前端Vue项目是http://127.0.0.1:8080,后端项目地址http://127.0.0.1:8000,那么这俩就属于不同源,前后端分离,就会遇到这个问题。

浏览器上就会报错,这个就是同源策略的保护,如果浏览器对javascript没有同源策略的保护,那么一些重要的机密网站将会很危险

但是注意,项目2中的访问已经发生了,说明是浏览器对非同源请求返回的结果做了拦截

CORS(跨域资源共享)简介

CORS需要浏览器和服务器同时支持。目前,大部分浏览器都支持该功能。

整个CORS通信过程,都是浏览器自动完成,不需要用户参与。对于开发者来说,CORS通信与同源的AJAX通信没有差别,代码完全一样。浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。

因此,实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信,只需要在响应头中指定,允许跨域即可

比较老的技术比如:jsonp技术,如果出现了跨域问题它可以通过img,script,link标签的连接功能,利用js的漏洞执行回调函数解决

jsonp

CORS分类

浏览器将CORS请求分成两类:简单请求(simple request)和非简单请求(not-so-simple request)

如何区分这两种?

只要同时满足以下两大条件,就属于简单请求,否则就是非简单请求

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

比如,post请求,josn格式是什么请求? 非简单请求

简单请求和非简单请求的区别

  • 简单请求:一次请求,直接发真正的请求,如果允许,数据拿回来,如果不允许,浏览器拦截
  • 非简单请求:两次请求,在发送数据之前会先发一次请求用于做“预检”,只有“预检”通过后才再发送一次请求用于数据传输。非简单请求发两次,第一次是OPTIONS请求,如果允许跨域,再发真正的请求

解决跨域

方式一:

  1. 简单请求再响应头中加入:"Access-Control-Allow-Origin":"*"

  2. 非简单,咱们要加判断,如果是OPTIONS请求,在响应头中加入允许

    # DRF中使用
    Response(result=res.data,headers={"Access-Control-Allow-Origin":"*"})

方式二

django中写个中间件,处理跨域,配置到配置文件

from django.utils.deprecation import MiddlewareMixin
class CorsMiddleWare(MiddlewareMixin):
def process_response(self,request,response):
if request.method=="OPTIONS":
#可以加*
response["Access-Control-Allow-Headers"]="Content-Type"
response["Access-Control-Allow-Origin"] = "*"
return response

方式三

使用第三方模块django-cors-headers

  1. 下载pip install django-cors-headers

  2. app注册

 INSTALLED_APPS = (
...
'corsheaders',
...
)
  1. 中间件注册
  MIDDLEWARE = [
# Or MIDDLEWARE_CLASSES on Django < 1.10
...
'corsheaders.middleware.CorsMiddleware',
...
]
  1. 配置文件配置
CORS_ALLOW_CREDENTIALS = True
CORS_ORIGIN_ALLOW_ALL = True
CORS_ORIGIN_WHITELIST = (
'*'
)
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',
)

轮播图前后端数据互通

settings.js

export default {
base_url: "http://127.0.0.1:8000/api/vi/"
}

banner.vue

<template>
<div class="banner">
<el-carousel :interval="5000" arrow="always" height="400px">
<el-carousel-item v-for="item in banner_list">
<img :src="item.image" alt="">
</el-carousel-item>
</el-carousel>
</div>
</template> <script> export default {
name: "Banner",
data(){
return {
banner_list:[]
}
},
created() {
this.$axios.get(this.$settings.base_url+'home/banner/').then(res=>{
if(res.data.status==100){
this.banner_list=res.data.result
console.log(this.banner_list)
}
})
}
}
</script> <style scoped> el-carousel-item {
height: 400px;
min-width: 1200px;
} .el-carousel__item img {
height: 400px;
margin-left: calc(50% - 1920px / 2);
}
</style>

后端自定义配置

在setting文件夹下新建 user_settings.py,我们可以把用户自己的配置放在这个配置文件中

BANNER_COUNT=3

可以继续在主配置文件导入继续使用

# 在dev.py中导入
# 导入用户自定义的配置
from .user_settings import *

Luffy /3/ 前台主页搭建&轮播图接口的更多相关文章

  1. day76:luffy:项目前端环境搭建&轮播图的实现

    目录 1.项目前端环境搭建 1.创建项目目录 2.前端初始化全局变量和全局方法 3.跨域CORS 4.axios配置 2.轮播图功能的实现 1.安装依赖模块 2.上传文件相关配置 3.注册home子应 ...

  2. 前台主页搭建、后台主页轮播图接口设计、跨域问题详解、前后端互通、后端自定义配置、git软件的初步介绍

    今日内容概要 前台主页 后台主页轮播图接口 跨域问题详解 前后端打通 后端自定义配置 git介绍和安装 内容详细 1.前台主页 Homeviwe.vue <template> <di ...

  3. Luffy之Xadmin以及首页搭建(轮播图,导航)

    1. 首页 1.1 轮播图 admin站点配置支持图片上传 pip install Pillow 默认情况下,Django会将上传的图片保存在本地服务器上,需要配置保存的路径.我们可以将上传的文件保存 ...

  4. Flutter学习五之网络请求和轮播图的实现

    上期讲到了,怎样实现一个下拉刷新和加载更多的列表,数据更新,需要使用到网络请求,在flutter中,怎样实现一个网络请求呢?官方使用的是dart io中的HttpClient发起的请求,但HttpCl ...

  5. 【VIP视频网站项目一】搭建视频网站的前台页面(导航栏+轮播图+电影列表+底部友情链接)

    首先来直接看一下最终的效果吧: 项目地址:https://github.com/xiugangzhang/vip.github.io 在线预览地址:https://xiugangzhang.githu ...

  6. 从零开始,搭建博客系统MVC5+EF6搭建框架(5),博客详情页、留言、轮播图管理、右侧统计博文

    一.博客系统进度回顾 上一遍博客介绍到,系统已经实现到了发布以及前台布局展示,接下来就是实现一些,详情页,留言.轮播图管理.右侧博文统计信息实现. 二.博客系统详情页实现 2.1先来看看详情页展示的效 ...

  7. 仿百度壁纸客户端(二)——主页自定义ViewPager广告定时轮播图

    仿百度壁纸客户端(二)--主页自定义ViewPager广告定时轮播图 百度壁纸系列 仿百度壁纸客户端(一)--主框架搭建,自定义Tab + ViewPager + Fragment 仿百度壁纸客户端( ...

  8. 潭州课堂25班:Ph201805201 django 项目 第二十三课 文章主页 轮播图前端实现 热门新闻推荐实现 详情页实现 (课堂笔记)

    前台代码 // 在static/js/news/index.js文件中 $(function () { // 新闻列表功能 let $newsLi = $(".news-nav ul li& ...

  9. 潭州课堂25班:Ph201805201 django 项目 第二十二课 文章主页 新闻列表页面滚动加载,轮播图后台实现 (课堂笔记)

    新建static/js/news/index.js文件 ,主要用于向后台发送请求, // 新建static/js/news/index.js文件 $(function () { // 新闻列表功能 l ...

随机推荐

  1. 生产环境频繁内存溢出,原来就是因为这个“String类”

    摘要:如果在程序中创建了比较大的对象,并且我们基于这个大对象生成了一些其他的信息,此时,一定要释放和这个大对象的引用关系,否则,就会埋下内存溢出的隐患. 本文分享自华为云社区<[高并发]你敢信? ...

  2. jQuery--文档处理案例

    需求 如上图,实现左右两边的选择菜单可以左右移动,'>'按钮一次只能移动被选中的一个菜单,'>>'按钮一次移动所有被选择的菜单,'>>>'按钮 将所有菜单进行移动, ...

  3. spring-boot-learning- Elasticsearch

    索引==数据库 类型==表 文档==表里面的记录 属性==表里面的列 使用RestFul风格elasticSearch进行操作 添加一个索引为megacorp,类型为employee,--id为1的文 ...

  4. NULL 是什么意思 ?

    NULL 这个值表示 UNKNOWN(未知):它不表示""(空字符串).对 NULL 这 个值的任何比较都会生产一个 NULL 值.您不能把任何值与一个 NULL 值进行比 较,并 ...

  5. 全网最硬核 Java 新内存模型解析与实验单篇版(不断更新QA中)

    个人创作公约:本人声明创作的所有文章皆为自己原创,如果有参考任何文章的地方,会标注出来,如果有疏漏,欢迎大家批判.如果大家发现网上有抄袭本文章的,欢迎举报,并且积极向这个 github 仓库 提交 i ...

  6. cpu内部组成

    计算机系统的硬件结构主要由四部分组成:控制器.运算器.内存和输入输出设备 其中,控制器和运算器统称为中央处理器.简称CPU.它是计算机硬件系统的指挥中心. 它包括控制器.运算器.寄存器三个部分,其中, ...

  7. 三、原理图生成网表并导入PCB放置元件

    1.生成网表 2.成功标志 3.新建PCB文件 4.导入网表至PCB 5.导入网表成功标志 6.创建.psm文件(绘制的封装格式为.dra文件,在PCB里面要以.psm的文件存在)  将丝印做成封装需 ...

  8. 王下邀月熊_Chevalier的前端每周清单系列文章索引

    感谢 王下邀月熊_Chevalier 分享的前端每周清单,为方便大家阅读,特整理一份索引. 王下邀月熊大大也于 2018 年 3 月 31 日整理了自己的前端每周清单系列,并以年/月为单位进行分类,具 ...

  9. 设计模式之简单工厂SimpleFactory的实现(配置文件)

    <?xml version="1.0" encoding="utf-8" ?> <configuration> <appSetti ...

  10. 软件构造实验-JFinal

    导入JFinal的demo 可以增删改查 根据demo以及自己的理解,使用JFinal实现学生信息管理系统.