前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python项目45-前后端分离Home主页及后台(开撸)

Python项目45-前后端分离Home主页及后台(开撸)

作者头像
DriverZeng
发布2022-09-26 14:03:02
4860
发布2022-09-26 14:03:02
举报
文章被收录于专栏:Linux云计算及前后端开发

-曾老湿, 江湖人称曾老大。


-多年互联网运维工作经验,曾负责过大规模集群架构自动化运维管理工作。 -擅长Web集群架构与自动化运维,曾负责国内某大型金融公司运维工作。 -devops项目经理兼DBA。 -开发过一套自动化运维平台(功能如下): 1)整合了各个公有云API,自主创建云主机。 2)ELK自动化收集日志功能。 3)Saltstack自动化运维统一配置管理工具。 4)Git、Jenkins自动化代码上线及自动化测试平台。 5)堡垒机,连接Linux、Windows平台及日志审计。 6)SQL执行及审批流程。 7)慢查询日志分析web界面。


前端页面

主页

我们把主页分成三部分: 1.导航栏 2.轮播图 3.页脚


图片

先把图片放入img目录中


全局做一个CSS reset

assets/css/global.css

代码语言:javascript
复制
/* 声明全局样式和项目的初始化样式 */
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; /* 合并边框 */
}

导航栏

创建Header组件

Header也就是我们的导航栏

componets/Header.vue

代码语言:javascript
复制
<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>

导入到主页中

首先注册导航栏,然后将导航栏添加到我们的主页中

代码语言:javascript
复制
<template>
    <div class="home">
        <Header/>
    </div>
</template>
<script>
    import Header from "@/components/Header";
    export default {
        name: 'home',
        components: {Header},
        Header,
    }
</script>


轮播图

创建轮播图组件Banner

components/Banner.vue

代码语言:javascript
复制
<template>
    <el-carousel height="520px" :interval="3000" 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-item v-for="banner in banner_list" :key="banner.name">
            <a :href="banner.link">
                <img :src="banner.image" alt="" :title="banner.note">
            </a>
        </el-carousel-item>

    </el-carousel>
</template>
<script>
    export default {
        name: "Banner",
        data() {
            return {
                banner_list: []
            }
        },
        created() {
            this.$axios({
                url: this.$settings.base_url + '/home/banners/',
                method: 'get',
            }).then(response => {
                // window.console.log(response.data);
                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>

注册Banner并且使用Banner

代码语言:javascript
复制
<template>
    <div class="home">
        <Header/>
        <Banner/>
    </div>
</template>

<script>
    import Header from '@/components/Header'
    import Banner from '@/components/Banner'

    export default {
        name: 'home',
        components: {
            Header,
            Banner,
        },
    }
</script>


页脚

在components目录下创建有个Footer组件

components/Footer.vue

代码语言:javascript
复制
<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.vue中注册页脚组件,并使用

代码语言:javascript
复制
<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设计


创建home模块

代码语言:javascript
复制
## 在apps目录下
(luffy) bash-3.2$ pwd
/Users/driverzeng/Desktop/luffy/luffyapi/luffyapi/apps

## 创建home
(luffy) bash-3.2$ python ../../manage.py startapp home

settings配置

注册drf组件和home组件

settings/dev.py

代码语言:javascript
复制
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework',
    'user',
    'home',
]

总路由做路由分发

luffyapi/urls.py

代码语言:javascript
复制
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),
    ## 路由分发user模块
    path('user/', include('user.urls')),
    ## 路由分发home模块
    path('home/', include('home.urls')),
    ## 图片上传路径,必须是正则路由
    re_path('^media/(?P<path>.*)', serve, {'document_root': settings.MEDIA_ROOT})
]

表设计


基础表设计设计BaseModel

utils/models.py

代码语言:javascript
复制
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

轮播图,表设计Banner

apps/home/models.py

代码语言:javascript
复制
from django.db import models
from utils.models import BaseModel


class Banner(BaseModel):
    image = models.ImageField(upload_to='banner', verbose_name='轮播图', null=True, blank=True)
    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

数据库迁移

代码语言:javascript
复制
(luffy) bash-3.2$ python manage.py makemigrations
(luffy) bash-3.2$ python manage.py migrate

子路由

apps/home/urls.py

代码语言:javascript
复制
from django.urls import path, re_path
from . import views

urlpatterns = [
    path('banners/', views.BannerListAPIView.as_view())
]

home序列化

apps/home/serializers.py

代码语言:javascript
复制
from rest_framework.serializers import ModelSerializer
from . import models


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

视图层

代码语言:javascript
复制
from rest_framework.generics import ListAPIView
from utils.repsonse 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

前后台跨域交互


解决后台跨域问题

安装django-cors-headers

代码语言:javascript
复制
(luffy) bash-3.2$ pip install django-cors-headers

配置允许跨域

settings/dev.py

代码语言:javascript
复制
### 注册跨域app
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework',
    ## 注册cors,解决跨域问题
    'corsheaders',
    'user',
    'home',
]

### 添加跨域中间件
MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    ## 添加跨域中间件
    'corsheaders.middleware.CorsMiddleware',
]

### 允许跨域源
CORS_ORIGIN_ALLOW_ALL = True

配置Banner组件ajax与后台交互

components/Banner.vue

代码语言:javascript
复制
<script>
    export default {
        name: "Banner",
        // 添加钩子,渲染页面的时候,axios与后台交互
        created() {
            this.$axios({
                url: this.$settings.base_url + '/home/banners/',
                method: 'get',
            }).then(response => {
                console.log(response.data)
            }).catch((errors) => {
                console.log(errors)
            })
        }
    }
</script>

因为数据库没有数据,但是我们交互成功了。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019-04-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前端页面
    • 主页
    • 后台home设计
      • 表设计
      • 前后台跨域交互
      相关产品与服务
      消息队列 TDMQ
      消息队列 TDMQ (Tencent Distributed Message Queue)是腾讯基于 Apache Pulsar 自研的一个云原生消息中间件系列,其中包含兼容Pulsar、RabbitMQ、RocketMQ 等协议的消息队列子产品,得益于其底层计算与存储分离的架构,TDMQ 具备良好的弹性伸缩以及故障恢复能力。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档