zoukankan      html  css  js  c++  java
  • luffy_01

    01首页

    1.1前端显示首页

    首页组件代码

    Home.vue

    <template>
      <div id="home">
        <Header/>
        <Banner/>
        <Footer/>
      </div>
    </template>
    
    <script>
    import Header from "./common/Header"
    import Banner from "./common/Banner"
    import Footer from "./common/Footer"
    
    export default {
      name:"Home",
      data(){
        return {
    
        }
      },
      components:{
        Header,
        Banner,
        Footer,
      }
    }
    </script>
    
    <style scoped>
    
    </style>
    
    

    首页头部子组件

    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/logo@2x.png" 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>
                      &nbsp;&nbsp;|&nbsp;&nbsp;
                      <router-link to="/register">注册</router-link>
                    </span>
                  </el-col>
                </el-row>
              </el-col>
            </el-row>
          </el-header>
        </el-container>
      </div>
    </template>
    
    <script>
      export default {
        name: "Header",
        data(){
          return {
            // 设置一个登录标识,表示是否登录
            token: false,
          };
        }
      }
    </script>
    
    <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{
         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{
         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{
         15px;
        height: auto;
        margin-left: 6px;
      }
      .cart-ico span{
        margin-left: 12px;
      }
      .member img{
         26px;
        height: 26px;
        border-radius: 50%;
        display: inline-block;
      }
      .member img:hover{
        border: 1px solid yellow;
      }
    
    </style>
    
    

    脚部子组件

    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>
    
    <script>
      export default {
        name:"Footer",
        data(){
          return {}
        }
      }
    </script>
    
    
    <style scoped>
    .footer{
       100%;
      height: 128px;
      background: #25292e;
    }
    .footer .el-container{
       1200px;
      margin: auto;
    }
    .footer .el-row {
      align-items: center;
      padding: 0 200px;
      padding-bottom: 15px;
       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>
    
    

    轮播图子组件

    Banner.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>
    
    <script>
      export default {
        name:"Banner",
        data(){
          return {
            banner_list:[
              {link:"http://www.baidu.com",img:"/static/banner/1.png"},
              {link:"http://www.baidu.com",img:"/static/banner/2.png"},
              {link:"http://www.baidu.com",img:"/static/banner/3.png"},
            ]
          };
        }
      }
    </script>
    
    <style>
    .el-carousel__arrow{
       100px!important;
      height: 100px!important;
    }
    .el-icon-arrow-left{
      font-size: 35px;
      margin-left: 50px;
    }
    .el-carousel__arrow--left{
      left: -50px;
    }
    </style>
    

    注册首页路由

    import Vue from "vue"
    import Router from "vue-router"
    
    // 导入需要注册路由的组件
    import Home from "../components/Home"
    Vue.use(Router);
    
    // 配置路由列表
    export default new Router({
      mode:"history",
      routes:[
        // 路由列表
        {
          name:"Home",
          path: "/home",
          component:Home,
        },
        {
          name:"Home",
          path: "/",
          component:Home,
        }
      ]
    })
    
    

    1.2轮播图功能实现

    安装依赖模块和配置

    图片处理模块

    前面已经安装了,如果没有安装则需要安装

    pip install pillow
    

    上传文件相关配置

    settings.py

    # 访问静态文件的url地址前缀
    STATIC_URL = '/static/'
    # 设置django的静态文件目录
    STATICFILES_DIRS = [
        os.path.join(BASE_DIR,"luffy/statics")
    ]
    
    # 项目中存储上传文件的根目录[暂时配置],注意,static目录需要手动创建否则上传文件时报错
    MEDIA_ROOT=os.path.join(BASE_DIR,"luffy/statics")
    # 访问上传文件的url地址前缀
    MEDIA_URL ="/media/"
    

    在xadmin中输出上传文件的Url地址

    总路由urls.py新增代码:

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

    创建轮播图的模型

    因为当前功能是drf的第一个功能,所以我们先创建一个子应用home,创建在luffy/apps目录下

    1557456645658

    注册home子应用,因为子应用的位置发生了改变,所以为了原来子应用的注册写法,所以新增一个导包路径:

    # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
    BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    
    # 新增一个系统导包路径
    import sys
    sys.path.insert(0,os.path.join(BASE_DIR,"apps"))
    
    
    
    INSTALLED_APPS = [
    	# 注意,加上drf框架的注册	
        'rest_framework',
        
        # 子应用
        'home',
    
    ]
    
    

    注意,pycharm会路径错误的提示。

    home/models.py

    from django.db import models
    
    # Create your models here.
    class BannerInfo(models.Model):
        """
        轮播图
        """
        # upload_to 存储子目录,真实存放地址会使用配置中的MADIE_ROOT+upload_to
        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='轮播图广告地址')
        orders = models.IntegerField(verbose_name='显示顺序')
        is_show=models.BooleanField(verbose_name="是否上架",default=False)
        is_delete=models.BooleanField(verbose_name="逻辑删除",default=False)
    
        class Meta:
            db_table = 'ly_banner'
            verbose_name = '轮播图'
            verbose_name_plural = verbose_name
    
        def __str__(self):
            return self.name
    
    

    数据迁移

    python manage.py makemigrations
    python manage.py migrate
    
    

    效果:

    1557457331569

    序列化器

    home/serializers.py

    from rest_framework.serializers import ModelSerializer
    from .models import BannerInfo
    class BannerInfoSerializer(ModelSerializer):
        """轮播图序列化器"""
        class Meta:
            model=BannerInfo
            fields = ("image","link")
    
    

    视图代码

    views.py

    from django.db.models import Q
    from rest_framework.generics import ListAPIView
    from .models import BannerInfo
    from .serializers import BannerInfoSerializer
    class BannerInfoListAPIView(ListAPIView):
        """
        轮播图列表
        """
        queryset = BannerInfo.objects.filter( Q(is_show=True) & Q(is_delete=False) ).order_by("-orders")
        serializer_class = BannerInfoSerializer
    
    

    路由代码

    urls.py

    from django.urls import path,re_path
    from . import views
    urlpatterns = [
        path(r"banner/",views.BannerInfoListAPIView.as_view()),
    ]
    
    

    把home的路由urls.py注册到总路由

    from django.urls import path,include
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('', include("home.urls")),
    ]
    
    
    

    访问http://api.luffycity.cn:8000/banner/,效果:

    1557457803586

    所以我们需要有一个后台提供数据.安装xadmin

    pip install https://codeload.github.com/sshwsfc/xadmin/zip/django2
    
    

    在配置文件中注册如下应用

    INSTALLED_APPS = [
        ...
        'xadmin',
        'crispy_forms',
        'reversion',
        ...
    ]
    
    # 修改使用中文界面
    LANGUAGE_CODE = 'zh-Hans'
    
    # 修改时区
    TIME_ZONE = 'Asia/Shanghai'
    
    

    xadmin有建立自己的数据库模型类,需要进行数据库迁移

    python manage.py makemigrations
    python manage.py migrate
    
    

    在总路由中添加xadmin的路由信息

    import xadmin
    xadmin.autodiscover()
    
    # version模块自动注册需要版本控制的 Model
    from xadmin.plugins import xversion
    xversion.register_models()
    
    urlpatterns = [
        path(r'xadmin/', xadmin.site.urls),
    ]
    
    

    如果之前没有创建超级用户,需要创建,如果有了,则可以直接使用之前的。

    python manage.py createsuperuser
    
    

    1557459230311

    给xadmin设置基本站点配置信息

    import xadmin
    from xadmin import views
    
    class BaseSetting(object):
        """xadmin的基本配置"""
        enable_themes = True  # 开启主题切换功能
        use_bootswatch = True
    
    xadmin.site.register(views.BaseAdminView, BaseSetting)
    
    class GlobalSettings(object):
        """xadmin的全局配置"""
        site_title = "路飞学城"  # 设置站点标题
        site_footer = "路飞学城有限公司"  # 设置站点的页脚
        menu_style = "accordion"  # 设置菜单折叠
    
    xadmin.site.register(views.CommAdminView, GlobalSettings)
    
    

    1557459373544

    注册模型到xadmin中

    在当前子应用中创建adminx.py,添加如下代码

    # 轮播图
    from .models import BannerInfo
    class BannerInfoModelAdmin(object):
        list_display=["name","orders","is_show"]
    xadmin.site.register(BannerInfo, BannerInfoModelAdmin)
    
    

    修改后端xadmin中子应用名称

    apps.py

    class HomeConfig(AppConfig):
        name = 'home'
        verbose_name = '我的首页'
    
    

    __init__.py

    default_app_config = "home.apps.HomeConfig"
    
    

    1557459568731

    给轮播图添加测试数据

    1557459669649

    添加几条测试数据效果:

    1557459949073

    客户端代码获取数据

    Banner.vue代码:

    <template>
      <div class="banner">
          <el-carousel trigger="click" height="506px">
          <el-carousel-item v-for="item in banner_list">
            <a :href="item.link"><img :src="item.image"></a>
          </el-carousel-item>
        </el-carousel>
      </div>
    </template>
    
    <script>
      export default {
        name:"Banner",
        data(){
          return {
            banner_list:[],
          };
        },
        created: function(){
          // 获取轮播图
          this.$axios.get(this.$settings+"/banner/").then(response => {
            console.log(response.data)
            this.banner_list = response.data
          }).catch(error => {
            console.log(error.response);
          });
        }
      }
    </script>
    
    

    效果:

    1557460383648

    1.3导航功能实现

    创建模型

    引入一个公共模型【抽象模型,不会在数据迁移的时候为它创建表】

    from django.db import models
    from luffy.utils.models import BaseModel
    # Create your models here.
    class BannerInfo(BaseModel):
        """
        轮播图
        """
        # upload_to 存储子目录,真实存放地址会使用配置中的MADIE_ROOT+upload_to
        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 = 'ly_banner'
            verbose_name = '轮播图'
            verbose_name_plural = verbose_name
    
        def __str__(self):
            return self.name
    
    
    class NavInfo(BaseModel):
        """
        导航
        """
        NAV_POSITION = (
            (0, 'top'),
            (1, 'footer')
        )
        name = models.CharField(max_length=50, verbose_name='导航名称')
        link = models.CharField(max_length=250, verbose_name='导航地址')
        opt = models.SmallIntegerField(choices=NAV_POSITION, default=0, verbose_name='位置')
    
        class Meta:
            db_table = 'ly_nav'
            verbose_name = '导航'
            verbose_name_plural = verbose_name
    
        def __str__(self):
            return self.name
    
    

    公共模型,保存项目的公共代码库目录下luffy/utils.py文件中。

    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)
        create_time = models.DateTimeField(auto_now_add=True,verbose_name="添加时间")
        update_time = models.DateTimeField(auto_now=True,verbose_name="更新时间")
    
        class Meta:
            # 设置当前模型在数据迁移的时候不要为它创建表
            abstract = True
    
    

    数据迁移

    python manage.py makemigrations
    python manage.py migrate
    
    

    序列化器代码

    from rest_framework.serializers import ModelSerializer
    from .models import NavInfo
    class NavInfoSerializer(ModelSerializer):
        """导航序列化器"""
        class Meta:
            model=NavInfo
            fields = ("name","link")
    
    

    视图代码

    views.py

    from .models import NavInfo
    from .serializers import NavInfoSerializer
    class NavInfoAPIView(ListAPIView):
        """
        导航列表
        """
        queryset = NavInfo.objects.filter( Q(is_show=True) & Q(is_delete=False) & Q(opt=0) ).order_by("-orders")
        serializer_class = NavInfoSerializer
    
    

    路由代码

    urls.py

    from django.urls import path,re_path
    from . import views
    urlpatterns = [
        ...
    	  path(r"nav/",views.NavInfoAPIView.as_view()),
    ]
    
    

    注册模型到xadmin中

    在当前子应用adminx.py,添加如下代码

    # 导航
    from home.models import NavInfo
    class NavInfoInfoModelAdmin(object):
        list_display=["name","link","is_show"]
    xadmin.site.register(NavInfo, NavInfoInfoModelAdmin)
    
    

    添加测试数据

    1557462133673

    客户端代码获取数据

    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 v-for="nav in nav_list" :span="3"><a :class="check(nav.link)?'current':''" :href="nav.link">{{nav.name}}</a></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/logo@2x.png" 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>
                      &nbsp;&nbsp;|&nbsp;&nbsp;
                      <router-link to="/register">注册</router-link>
                    </span>
                  </el-col>
                </el-row>
              </el-col>
            </el-row>
          </el-header>
        </el-container>
      </div>
    </template>
    
    <script>
      export default {
        name: "Header",
        data(){
          return {
            // 设置一个登录标识,表示是否登录
            token: false,
            nav_list:[],
          };
        },
        created() {
          // 获取导航
          this.$axios.get(this.$settings.Host+"/nav/").then(response=>{
            this.nav_list = response.data
            console.log(this.nav_list)
          }).catch(error=>{
            console.log(error.response)
          })
        },
        methods:{
          check(link){
              return link==window.location.pathname
          }
        }
      }
    </script>
    
    <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{
         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{
         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{
         15px;
        height: auto;
        margin-left: 6px;
      }
      .cart-ico span{
        margin-left: 12px;
      }
      .member img{
         26px;
        height: 26px;
        border-radius: 50%;
        display: inline-block;
      }
      .member img:hover{
        border: 1px solid yellow;
      }
    
    </style>
    
    
    
  • 相关阅读:
    CentOS 6.5、6.7 设置静态 ip 教程
    Nagios
    zabbix
    xml 的 <![CDATA["URL"]]>
    Don't make a promise when you are in Joy. Don't reply when you are Sad.Don't take decisions when you are Angry.Think Twice.Act Wise.
    DNS-2
    APM
    Time crumbles things; everything grows old under the power of Time and is forgotten through the lapse of Time
    CentOS 7 配置静态 ip
    AOP
  • 原文地址:https://www.cnblogs.com/pankypan/p/11300241.html
Copyright © 2011-2022 走看看