Django组合筛选
Posted xjt2018
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 " ></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 " ></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
以上是关于Django组合筛选的主要内容,如果未能解决你的问题,请参考以下文章