zoukankan      html  css  js  c++  java
  • 【Django】组合筛选

    组合筛选

    数据库表设计:

    from django.db import models
    
    class Direction(models.Model):
        '''
        视频方向:全栈、前端、后端、测试、运维、自动化
        '''
        name = models.CharField(max_length=32,verbose_name="方向名称")
        m = models.ManyToManyField("Classification")
    
        # 别名
        class Meta:
            verbose_name_plural = "方向分类"
    
        def __str__(self):
            return self.name
    
    
    class Classification(models.Model):
        '''
        语言分类:Python、Java、HTML、css、selenium、NodeJs、OpenStack
        '''
        name = models.CharField(max_length=32,verbose_name="视频分类")
    
        #别名
        class Meta:
            verbose_name_plural = "编程语言分类"
    
        def __str__(self):
            return self.name
    
    class Level(models.Model):
        title = models.CharField(max_length=32)
    
        class Meta:
            verbose_name_plural = "难度等级"
    
        def __str__(self):
            return self.title
    
    class Video(models.Model):
        status_choice = (
            (1,"上线"),(2,"下线")
        )
        status = models.IntegerField(choices=status_choice,default=1,verbose_name="状态")
        level = models.ForeignKey("Level",on_delete=models.CASCADE)
        classification = models.ForeignKey("Classification",null=True,on_delete=models.CASCADE,verbose_name="语言分类")
        weight = models.IntegerField(verbose_name="权重(按照从大到小排列)")
    
        title = models.CharField(max_length=32,verbose_name="标题")
        summary = models.CharField(max_length=512, verbose_name="简介")
        img = models.ImageField(verbose_name="图片",upload_to="static/images")
        href = models.URLField(verbose_name="视频地址",max_length=64)
    
        class Meta:
            db_table = "Video"
            verbose_name_plural = "视频"
    
        def __str__(self):
            return self.title

    路由分发:

    from django.contrib import admin
    from django.conf.urls import url
    from app01 import views
    
    urlpatterns = [
        url('admin/', admin.site.urls),
        url('^video-(?P<classification_id>d+)-(?P<level_id>d+)-(?P<status>d+).html/$', views.video),
        url('^video2-(?P<direction_id>d+)-(?P<classification_id>d+)-(?P<level_id>d+).html/$', views.video2),
    ]

    版本1、一对多筛选

    效果:

    视图函数views.py

    from django.shortcuts import render
    from app01.models import Classification,Direction,Level,Video
    
    def video(request,*args,**kwargs):
        condition = {
            # "classification_id":0
            # "level_id":0,
            # "status":0
        }
        print("kwargs--->",kwargs)      #url的  video-1-1 的分类classification_id=1  level_id=1 保存到kwargs
        # kwargs - --> {'classification_id': '1', 'level_id': '1','status':'1'}     #键值对 都是字符串格式
        for k,v in kwargs.items():
            temp = int(v)
            kwargs[k] = temp
            if temp:                    #当temp==0 时,condition=={}  即filter() 过滤条件为空,匹配所有
                condition[k] = temp
    
        classification_list = Classification.objects.all()
        level_list = Level.objects.all()
        status_list = Video.status_choice
        # status_choice = (
        #     (1, "上线"), (2, "下线")
        # )
        # 在模板语言中 循环体内调用方式为  item.0  item.1      ,这样子很不直观
        # 可以将status_choice 改变为 [{'id':1,'name':'上线'},{'id':2,'name':'下线'}]
        status_list = list(map(lambda x:{"id":x[0],"name":x[1]},status_list))
    
        video_list = Video.objects.filter(**condition)
    
        return render(
            request,
            "video.html",
            {
                "classification_list":classification_list,
                "level_list":level_list,
                "kwargs":kwargs,
                "video_list":video_list,
                "status_list":status_list,
            }
        )

    视图函数views.py

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>视频-组合筛选</title>
        <style>
            a.btn{
                font-size: 16px;
                border: 1px solid orange;
                font-weight: 500;
                padding: 10px;
                text-decoration: none;
                border-radius: 5px;
            }
            .row{
                font-size: 20px;
                margin-top: 30px;
            }
            .active{
                background-color: orangered;
                color: white;
                font-weight: 700;
            }
            .resultShow{
                border: 1px dotted darkblue;
            }
            .resultShow div{
                margin: 20px;
            }
        </style>
    </head>
    <body>
    <div class="contents">
        <div class="selectorBox">
            <h1>筛选</h1>
            <div class="classes row">
                <p>编程语言分类:</p>
                {% if kwargs.classification_id == 0 %}
                    <a href="/video-0-{{ kwargs.level_id }}-{{ kwargs.status }}.html" class="active btn">全部</a>
                {% else %}
                    <a href="/video-0-{{ kwargs.level_id }}-{{ kwargs.status }}.html" class="btn">全部</a>
                {% endif %}
                {% for item in classification_list %}
                    {% if item.id == kwargs.classification_id %}
                        <a href="/video-{{ item.id }}-{{ kwargs.level_id }}-{{ kwargs.status }}.html" class="active btn">{{ item.name }}</a>
                    {% else %}
                        <a href="/video-{{ item.id }}-{{ kwargs.level_id }}-{{ kwargs.status }}.html" class="btn">{{ item.name }}</a>
                    {% endif %}
                {% endfor %}
            </div>
            <div class="level row">
                <p>难度等级:</p>
               {% if kwargs.level_id == 0 %}
                    <a href="/video-{{ kwargs.classification_id }}-0-{{ kwargs.status }}.html" class="active btn">全部</a>
                {% else %}
                    <a href="/video-{{ kwargs.classification_id }}-0-{{ kwargs.status }}.html" class="btn">全部</a>
                {% endif %}
                {% for item in level_list %}
                    {% if item.id == kwargs.level_id %}
                        <a href="/video-{{ kwargs.classification_id }}-{{ item.id }}-{{ kwargs.status }}.html" class="active btn">{{ item.title }}</a>
                    {% else %}
                        <a href="/video-{{ kwargs.classification_id }}-{{ item.id }}-{{ kwargs.status }}.html" class="btn">{{ item.title }}</a>
                    {% endif %}
                {% endfor %}
            </div>
            <div class="status row">
                <p>上线/下线:</p>
               {% if kwargs.status == 0 %}
                    <a href="/video-{{ kwargs.classification_id }}-{{ kwargs.level_id }}-0.html" class="active btn">全部</a>
                {% else %}
                    <a href="/video-{{ kwargs.classification_id }}-{{ kwargs.level_id }}-0.html" class="btn">全部</a>
                {% endif %}
                {% for item in status_list %}
                    {% if item.id == kwargs.status %}
                        <a href="/video-{{ kwargs.classification_id }}-{{ kwargs.level_id }}-{{ item.id }}.html" class="active btn">{{ item.name }}</a>
                    {% else %}
                        <a href="/video-{{ kwargs.classification_id }}-{{ kwargs.level_id }}-{{ item.id }}.html" class="btn">{{ item.name }}</a>
                    {% endif %}
                {% endfor %}
            </div>
    
        </div>
        <div class="resultBox">
            <h1>搜索结果</h1>
            <div class="resultShow">
                {% for video in video_list %}
                    <div><span>标题:</span>  <span style="font-size: 26px;font-weight: 700;color: orangered">{{ video.title }}</span></div>
                    <div><span>简介:</span>  <span>{{ video.summary }}</span></div>
                    <div><span>图片:</span><img src="/static/images/{{ video.img }}" alt=""></div>
                    <div><span>视频href:</span>  <a href="{{ video.href }}">{{ video.href }}</a></div>
                    <hr>
                {% endfor %}
            </div>
        </div>
    </div>
    
    </body>
    </html>
    

      

    版本2、多对多筛选

    效果:

    视图函数views.py

    from django.shortcuts import render
    from app01.models import Classification,Direction,Level,Video
    
    def video2(request,*args,**kwargs):
        print(kwargs)
        direction_list = Direction.objects.all()
    
        for k,v in kwargs.items():
            kwargs[k] = int(v)
        direction_id = kwargs["direction_id"]
        classification_id = kwargs["classification_id"]
        condition = {}
        classification_id_list = []
    
        if direction_id:
            direction_obj = Direction.objects.filter(id=direction_id).first()
            vlist = direction_obj.m.all().values_list("id")
    
            if vlist:
                classification_id_list = list(zip(*vlist))[0]
    
            if classification_id == 0:
                condition["classification_id__in"] = classification_id_list
            else:
                if classification_id in classification_id_list:
                    condition["classification_id"] = classification_id
                else:
                    ###方向id=1时 分类id=[1,2,3] 但是你url传入的分类id=4 不在[1,2,3]中。则classification_id == direction_id所对应的则classification_id
                    condition["classification_id__in"] = classification_id_list
                    classification_id = 0
    
            cls_condition = {"id__in": list(classification_id_list)}
            classification_list = Classification.objects.filter(**cls_condition)
        else:
            classification_list = Classification.objects.all()
    
    
    
        if kwargs["level_id"]:
            condition["level_id"] = kwargs["level_id"]
    
    
        level_list = Level.objects.all()
        video_list = Video.objects.filter(**condition)
    
        print(condition,video_list)
        return render(request,"video2.html",{
            "direction_list": direction_list,
            "classification_list": classification_list,
            "level_list": level_list,
            "classification_id":classification_id,
            "kwargs": kwargs,
            "video_list": video_list,
        })

    模板HTML:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>组合筛选2</title>
        <style>
            a.btn{
                font-size: 16px;
                border: 1px solid orange;
                font-weight: 500;
                padding: 10px;
                text-decoration: none;
                border-radius: 5px;
            }
            .row{
                font-size: 20px;
                margin-top: 30px;
            }
            .active{
                background-color: orangered;
                color: white;
                font-weight: 700;
            }
            .resultShow{
                border: 1px dotted darkblue;
            }
            .resultShow div{
                margin: 20px;
            }
        </style>
    </head>
    <body>
    <div class="contents">
        <div class="selectorBox">
            <h1>筛选</h1>
            <div class="directions row">
                <p>视频方向:</p>
                {% if kwargs.direction_id == 0 %}
                    <a href="/video2-0-{{ kwargs.classification_id }}-{{ kwargs.level_id }}.html" class="btn active">全部</a>
                {% else %}
                    <a href="/video2-0-{{ kwargs.classification_id }}-{{ kwargs.level_id }}.html" class="btn">全部</a>
                {% endif %}
                {% for direction in direction_list %}
                    {% if kwargs.direction_id == direction.id %}
                        <a href="/video2-{{ direction.id }}-{{ kwargs.classification_id }}-{{ kwargs.level_id }}.html" class="btn active">{{ direction.name }}</a>
                    {% else %}
                        <a href="/video2-{{ direction.id }}-{{ kwargs.classification_id }}-{{ kwargs.level_id }}.html" class="btn">{{ direction.name }}</a>
                    {% endif %}
                {% endfor %}
            </div>
            <div class="classifications row">
                <p>语言分类:</p>
                {% if classification_id == 0 %}
                    <a href="/video2-{{ kwargs.direction_id }}-0-{{ kwargs.level_id }}.html" class="btn active">全部</a>
                {% else %}
                    <a href="/video2-{{ kwargs.direction_id }}-0-{{ kwargs.level_id }}.html" class="btn">全部</a>
                {% endif %}
                {% for item in classification_list %}
                    {% if classification_id == item.id %}
                        <a href="/video2-{{ kwargs.direction_id }}-{{ item.id }}-{{ kwargs.level_id }}.html" class="btn active">{{ item.name }}</a>
                    {% else %}
                        <a href="/video2-{{ kwargs.direction_id }}-{{ item.id }}-{{ kwargs.level_id }}.html" class="btn">{{ item.name }}</a>
                    {% endif %}
                {% endfor %}
            </div>
            <div class="levels row">
                <p>难度等级:</p>
                {% if kwargs.level_id == 0 %}
                    <a href="/video2-{{ kwargs.direction_id }}-{{ kwargs.classification_id }}-0.html" class="btn active">全部</a>
                {% else %}
                    <a href="/video2-{{ kwargs.direction_id }}-{{ kwargs.classification_id }}-0.html" class="btn">全部</a>
                {% endif %}
                {% for item in level_list %}
                    {% if kwargs.level_id == item.id %}
                        <a href="/video2-{{ kwargs.direction_id }}-{{ kwargs.classification_id }}-{{ item.id }}.html" class="btn active">{{ item.title }}</a>
                    {% else %}
                        <a href="/video2-{{ kwargs.direction_id }}-{{ kwargs.classification_id }}-{{ item.id }}.html" class="btn">{{ item.title }}</a>
                    {% endif %}
                {% endfor %}
            </div>
    
        </div>
        <div class="resultBox">
            <h1>搜索结果</h1>
            <div class="resultShow">
                {% for video in video_list %}
                    <div><span>标题:</span>  <span style="font-size: 26px;font-weight: 700;color: orangered">{{ video.title }}</span></div>
                    <div><span>简介:</span>  <span>{{ video.summary }}</span></div>
                    <div><span>图片:</span><img src="/static/images/{{ video.img }}" alt=""></div>
                    <div><span>视频href:</span>  <a href="{{ video.href }}">{{ video.href }}</a></div>
                    <hr>
                {% endfor %}
            </div>
        </div>
    </div>
    
    </body>
    </html> 

    重要知识点总结:

    1、路由中正则使用有名分组,传入的信息以字典格式保存在 视图函数的 kwargs中

    url('^video-(?P<classification_id>d+)-(?P<level_id>d+)-(?P<status>d+).html/$', views.video),
    
    -------------------------------------------------------------------------views.py
    print("kwargs--->",kwargs)      #url的  video-1-1 的分类classification_id=1  level_id=1 保存到kwargs
    # kwargs - --> {'classification_id': '1', 'level_id': '1','status':'2'}     #键值对 都是字符串格式

    2、map()  函数的用法:

    yuanzu = ((1,"在线"),(2,"下线"))
    
    status_list = list(map(lambda x:{"id":x[0],"name":x[1]},yuanzu))
    print(status_list)
    #[{'id': 1, 'name': '在线'}, {'id': 2, 'name': '下线'}]
    
    s_li = ["beijing",3,"zhejiang",7]
    def multi(s):
        if type(s)==int:
            return s**2
        elif type(s) == str:
            return s.upper()
        else:
            return s
    
    print(list(map(lambda x:multi(x),s_li)))
    #['BEIJING', 9, 'ZHEJIANG', 49]
    

    3、zip() 函数用法:

    # zip() 方法
    v1 = [1,2,3]
    v2=[44,55,66]
    
    print(list(zip(v1,v2)))         #二合一
    #[(1, 44), (2, 55), (3, 66)]
    print(list(zip(*[[11,22,33],[1,5,9]])))     #一分二
    #[(11, 1), (22, 5), (33, 9)]
    print(list(zip(*[(11,22,33),(44,55,66,77)])))
    # [(11, 44), (22, 55), (33, 66)]
    

    4、模板语言 if 判断是否选中,以及for循环遍历

    <div class="classes row">
                <p>编程语言分类:</p>
                {% if kwargs.classification_id == 0 %}
                    <a href="/video-0-{{ kwargs.level_id }}-{{ kwargs.status }}.html" class="active btn">全部</a>
                {% else %}
                    <a href="/video-0-{{ kwargs.level_id }}-{{ kwargs.status }}.html" class="btn">全部</a>
                {% endif %}
                {% for item in classification_list %}
                    {% if item.id == kwargs.classification_id %}
                        <a href="/video-{{ item.id }}-{{ kwargs.level_id }}-{{ kwargs.status }}.html" class="active btn">{{ item.name }}</a>
                    {% else %}
                        <a href="/video-{{ item.id }}-{{ kwargs.level_id }}-{{ kwargs.status }}.html" class="btn">{{ item.name }}</a>
                    {% endif %}
                {% endfor %}
    </div>
    

    5、多对多筛选条件判断

    def video2(request,*args,**kwargs):
        print(kwargs)
        direction_list = Direction.objects.all()
        
        #将字典 value值变为整数
        for k,v in kwargs.items():
            kwargs[k] = int(v)
        direction_id = kwargs["direction_id"]
        classification_id = kwargs["classification_id"]
        condition = {}
        classification_id_list = []
        #如果direction_id !=0
        if direction_id:
            direction_obj = Direction.objects.filter(id=direction_id).first()
            vlist = direction_obj.m.all().values_list("id")
            #如果方向id 下对应有分类
            if vlist:
                classification_id_list = list(zip(*vlist))[0]
            #分类id=0
            if classification_id == 0:
                condition["classification_id__in"] = classification_id_list
            else:
                # 分类id 在方向id对应的分类列表中
                if classification_id in classification_id_list:
                    condition["classification_id"] = classification_id
                else:
                    ###方向id=1时 分类id=[1,2,3] 但是你url传入的分类id=4 不在[1,2,3]中。则classification_id == direction_id所对应的则classification_id
                    condition["classification_id__in"] = classification_id_list
                    classification_id = 0
    
            cls_condition = {"id__in": list(classification_id_list)}
            classification_list = Classification.objects.filter(**cls_condition)
        else:
            classification_list = Classification.objects.all()
    
        if kwargs["level_id"]:
            #如果等级id不为0 则写入条件字典
            condition["level_id"] = kwargs["level_id"]
    
        level_list = Level.objects.all()
        video_list = Video.objects.filter(**condition)
    
        print(condition,video_list)
        return render(request,"video2.html",{
            "direction_list": direction_list,
            "classification_list": classification_list,
            "level_list": level_list,
            "classification_id":classification_id,
            "kwargs": kwargs,
            "video_list": video_list,
        })
    

    参考:

    https://www.cnblogs.com/ccorz/p/5985205.html

    https://www.jianshu.com/p/8402823e8f1b

  • 相关阅读:
    Fedora 19 配置参考
    Lua 函数、闭包、尾调用总结
    基于MFC简单图片裁剪工具
    【OpenGL 学习笔记04】顶点数组
    【OpenGL 学习笔记03】点画多边形
    【OpenGL 学习笔记02】宽点画线
    【OpenGL 学习笔记01】HelloWorld示例
    【SSH + BootStrap】实现的无线点餐系统
    【C++ 基础 11】 函数指针总结
    【C++基础 10】四种cast转换的区别
  • 原文地址:https://www.cnblogs.com/XJT2018/p/11381325.html
Copyright © 2011-2022 走看看