路飞项目前后端配置

2022/4/21 6:17:03

本文主要是介绍路飞项目前后端配置,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

内容回顾

# 1 封装Respons---》以后的Response使用咱们自己的---》APIRespon--》简化操作
class APIRresponse(Response):
  def __init__(self,status,msg,http_status,header,**kwargs):
    	data={
        status:status,
        msg:msg
      }
      data.update(kwargs)
      super().__init__(data=data)
      # Response(data=data,status=http_status,header=header)
      
# 2 后端数据库配置
	-创建了一个用户,把luffy库授权给用户
  -后台使用mysql数据库
  	-pymysql:3.x
    -mysqlclient:3.x
 	-密码的隐藏---》不要直接写在源文件中
  -win:环境变量配置--->获取试一下
  
  
# 3 创建前端项目
	-vue create luffycity
  -使用了axios,elementui,bootstrap,jq
  -步骤:安装,main.js配置
  -全局的样式:清空标签的默认属性
  -全局js:export default {}--->后端地址(上线,后端地址会变化)
    
    
    
  
# mac,linux下--》修改.bashrc / .zshrc
~/.bash_profile 每个用户都可使用该文件输入专用于自己使用的shell信息,当用户登录时,该文件仅仅执行一次! 默认情况下,他设置一些环境变量,执行用户的.bashrc文件。
~/.bashrc 该文件包含专用于你的bash shell的bash信息,当登录时以及每次打开新的shell时,该该文件被读取

内容概要

1 前台主页

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>

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>

Header.vue

<template>
    <div class="header">
        <div class="slogan">
            <p>老男孩IT教育 | 帮助有志向的年轻人通过努力学习获得体面的工作和生活</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>

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>

2 后台主页轮播图接口

# 轮播图接口---》带着大家写

# 导航条写死的---》如果想动态变化---》也要写成接口
# 首页推荐的8个课程---》接口---》按销量排序取前8个课程

2.1 表设计

**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  # 表示它是虚拟的,不在数据库中生成表,它只用来做继承

**Banner表**

from django.db import models

# Create your models here.
# 轮播图接口---》轮播图表
from utils.model import BaseModel
class Banner(BaseModel):
    # 顺序,插入时间, 是否显示,是否删除。。。----》后期写课程的表也会用到这些字段--->仿AbstractUser,写一个基表,以后继承这个表
    # 继承过来,只需要写自有字段即可:title,image,info,link
    title = models.CharField(max_length=16, unique=True, verbose_name='名称')
    image = models.ImageField(upload_to='banner', verbose_name='图片')
    # 写接口---》app---》前端配合一个接口---》实现打开app,就有广告图片---》点击广告图片调整到app内部或者使用浏览器打开
    # 一打开app,先打开的页面是什么,写app的人写的---》整一张大图充满全屏即可--》配合一个接口,返回一张大图
    # app打开广告接口---》{code:100,msg:成功,img:{img:127.0.0.1/img/1.png,link:'www.baidu.com',type:2}}
    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

2.2 迁移数据,创建超级用户

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

2.3 引入simpleui

# 下载
pip install django-simpleui
# 注册app
INSTALLED_APPS = [
      'simpleui',
      ...
  ]
# 在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 = '自定义按钮'

2.4 轮播图接口

# 返回数据格式
{code:100,msg:成功,result:[{img:地址,link:跳转地址,orders:顺序,title:名字},{img:地址,link:跳转地址,orders:顺序,title:名字}]}

**总路由**

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

**home路由**

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']

3 跨域问题详解

# 现在写好了后端接口,前端加载数据---》加载不过来,报错,--》报跨域的错误

#  同源策略 ---》浏览器的规定
	-请求的url地址,必须与浏览器上的url地址处于同域上,也就是域名,端口,协议相同,否则,加载回来的数据就会禁止
  -前端:http://127.0.0.1:8080
  -后端:http://127.0.0.1:8000
  -这俩属于不同源,协议,地址一样,但是端口不一样,所以请求成功,但是到了浏览器被禁止掉了,因为浏览器的同源策略
 	-前后端分离,就会遇到这个问题,解决这个问题
  

# jsonp:出现了跨域问题---》有的东西不出跨域问题---》img,script,link--》回调
# https://www.zhihu.com/question/19966531


# 通过CORS(跨域资源共享)
CORS需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能

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

# 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请求,如果允许跨域,再发真正的请求


# 解决跨域-->分成简单和非简单请求处理
	-简单请求再响应头中加入:"Access-Control-Allow-Origin":"*"
  -非简单,咱们要加判断,如果是OPTIONS请求,在响应头中加入允许

# 自行解决跨域---》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
      
      
 # 经常遇到的东西,一定会有第三方解决方案---》我们使用第三方解决
	-第一步:下载:pip install django-cors-headers
	-第二步:app中注册
    INSTALLED_APPS = (
    ...
    'corsheaders',
    ...
  )
  -第三步:中间件注册
    MIDDLEWARE = [  # Or MIDDLEWARE_CLASSES on Django < 1.10
    ...
    'corsheaders.middleware.CorsMiddleware',
    ...
  ]
  -第四步:配置文件配置
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',
)
  	

4 前后端打通

<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>

5 后端自定义配置

# 在setting文件夹下新建 user_settings.py
# 用户自己的配置,单独放到另一个py文件中
BANNER_COUNT=3


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

6 git介绍和安装

# 公司里是协同开发,多人开发同一个项目
# 代码已经写到v3版本了,忽然想看一下v1版本什么样
# git:代码版本管理工具,软件,同类型的是svn,用得少
		-帮助开发者合并开发的代码
		-如果出现冲突代码的合并,会提示后提交合并代码的开发者,让其解决冲突
    -做代码版本管理,可以快速回到某个版本上
  
# win:下载
https://git-scm.com/download
  
# mac下载:https://github.com/timcharper/git_osx_installer/releases/download/2.2.1/git-2.2.1-intel-universal-mavericks.dmg

# 一路下一步,其他都不用选


这篇关于路飞项目前后端配置的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程