zoukankan      html  css  js  c++  java
  • 17.导航

    导航

    后台导航初模型:home/models.py
    from django.db import models
    class Banner(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
    
    class Nav(models.Model):
        """导航"""
        NAV_POSITION = (
            (0, '顶部导航'),
            (1, '底部导航') 
        )
        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='位置')
        # 共有部分
        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 = 'luffy_nav'
            verbose_name = '导航'
            verbose_name_plural = verbose_name
    
        def __str__(self):
            return self.name
    
    改造model:home/models.py => luffyapi/utils/models.py
    # home/models.py 
    # 轮播图模型
    from django.db import models
    from luffyapi.utils.models import BaseModel
    class Banner(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
    
    class Nav(models.Model):
        """导航"""
        NAV_POSITION = (
            (0, '顶部导航'),
            (1, '底部导航') 
        )
        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='位置')
        # 共有部分
        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_nav'
            verbose_name = '导航'
            verbose_name_plural = verbose_name
    
        def __str__(self):
            return self.name
    
    # luffyapi/utils/models.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)
        created_time = models.DateTimeField(verbose_name="创建时间", auto_now_add=True, null=True, blank=True)
        updated_time = models.DateTimeField(verbose_name="更新时间", auto_now=True, null=True, blank=True)
        class Meta:
            # 抽象模型,一般用于设置公共模型字段的,一旦设置这个相关以后,那么dajngo在数据迁移的时候就不会为这个模型单独创建一个数据表了
            abstract=True
    
    # 在项目根目录下的终端
    python manage.py makemigrations
    python manage.py migrate
    
    序列化:home/serializers.py
    from .models import Nav
    class NavModelSerializer(serializers.ModelSerializer):
        """导航菜单序列化器"""
        class Meta:
            model = Nav
            fields = ["name", "link", "opt"]
    
    视图:home/views.py
    from .models import Nav
    from .serializers import NavModelSerializer
    class NavListAPIView(ListAPIView):
        queryset = Nav.objects.filter(is_show=True, is_delete=False).order_by("orders")[:constant.NAV_LENGTH]
        serializer_class = NavModelSerializer
    
    配置常量:settings/constant.py
    # 导航的显示数量
    NAV_LENGTH = 7
    
    子路由:home/nav
    # home/nav
    path("nav/",views.NavListAPIView.as_view()),
    
    xadmin注册model
    from .models import Nav
    xadmin.site.register(Nav)
    
    
    录入数据
    """
    1 上架 免费课 /course 顶部导航
    2 上架 轻客 /light-course 顶部导航
    10 上架 关于我们 /about 底部导航
    ...
    """
    
    
    前端组件改造
    <template>
        <div class="header-box">
            <div class="header">
                <div class="content">
                    <div class="logo full-left">
                        <router-link to="/"><img @click="jump('/')" src="@/assets/image/logo.svg" alt=""></router-link>
                    </div>
                    <ul class="nav full-left">
                        <li v-for="nav in nav_list"><span @click="jump(nav.link)" :class="this_nav==nav.link?'this':''">{{nav.name}}</span></li>
                    </ul>
                    <div class="login-bar full-right">
                        <div class="shop-cart full-left">
                            <img src="@/assets/image/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: "",
                    nav_list: [],
                }
            },
            created() {
                this.this_nav = localStorage.this_nav;
    
                let _this = this
                // 获取服务端的导航信息
                this.$axios({
                    url: this.$settings.Host + "/home/nav/"
                }).then(function (response) {
                    _this.nav_list = response.data
                }).catch(function(error) {
                    console.log(error)
                });
            },
            methods: {
                jump(location) {
                    localStorage.this_nav = location;
                    // vue-router除了提供router-link标签跳转页面以外,还提供了 js跳转的方式
                    this.$router.push(location);
                }
            }
        }
    </script>
    
    <style scoped>
        .header-box {
            height: 80px;
        }
    
        .header {
             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- 1200px;
             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;
             88px;
            margin-top: 30px;
            line-height: 32px;
            text-align: center;
        }
    
        .header .login-bar .shop-cart:hover {
            background: #f0f0f0;
        }
    
        .header .login-bar .shop-cart img {
             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;
        }
    </style>
    
    
    

    底部导航

    视图改造
    from .models import Nav
    from .serializers import NavModelSerializer
    
    class NavHeaderListAPIView(ListAPIView):
        queryset = Nav.objects.filter(opt=1,is_show=True, is_delete=False).order_by("orders")[:constant.NAV_LENGTH]
        serializer_class = NavModelSerializer
    
    class NavFooterListAPIView(ListAPIView):
        queryset = Nav.objects.filter(opt=2,is_show=True, is_delete=False).order_by("orders")[:constant.NAV_LENGTH]
        serializer_class = NavModelSerializer
    
    
    子路由改造
    path("nav/header/",views.NavHeaderListAPIView.as_view()),
    path("nav/footer/",views.NavFooterListAPIView.as_view()),
    
    
    xadmin注册model改造
    from .models import Nav
    xadmin.site.register(Nav)
    
    
    前端组件改造
    """ Header.vue
    
    <ul class="nav full-left">
    	<li v-for="nav in nav_list">
    		<span @click="jump(nav.link)" :class="this_nav==nav.link?'this':''">{{nav.name}}</span>
    	</li>
    </ul>
    
    
    created() {
    	this.this_nav = localStorage.this_nav;
    
        let _this = this
        // 获取服务端的导航信息
        this.$axios({
            url: this.$settings.Host + "/home/nav/header/"
        }).then(function (response) {
            _this.nav_list = response.data
        }).catch(function(error) {
            console.log(error)
        });
    },
    
    """
    
    """ Footer.vue
    
    <ul>
    	<li v-for="nav in nav_list">
    		<a :href="nav.link">{{nav.name}}</a>
    	</li>
    </ul>
    
    
    data: function () {
        return {
            nav_list:[]
        }
    }
    
    created: function ()  {
        let _this = this
        // 获取服务端的导航信息
        this.$axios({
            url: this.$settings.Host + "/home/nav/footer/"
        }).then(function (response) {
            _this.nav_list = response.data
        }).catch(function(error) {
            console.log(error)
        });
    },
    
    .footer a {
        color: white;
    }
    """
    
  • 相关阅读:
    HTML表格和列表笔记&练习<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>关于表格的一些练习</title> </head> <body> <p>一个普通基本的表格</p> <table border="5&
    HTML中的CSS类型
    html关于图片和链接的笔记
    实现窗体背景透明
    HTML控件篇 -- input
    AngularJs的$http使用随笔
    Win7启动修复(Ubuntu删除后进入grub rescue的情况)
    2013年9月30日我的博客园开通啦
    将excel表格导入到DataGridView
    c#中,点击一个菜单项后调用exe文件
  • 原文地址:https://www.cnblogs.com/abdm-989/p/14259771.html
Copyright © 2011-2022 走看看