筛选功能-组合搜索
model.py

# 视频方向 class Direction(models.Model): ''' 方向:自动化,测试,运维,前端 ''' name = models.CharField(verbose_name='名称', max_length=32) classification = models.ManyToManyField('Classification') class Meta: db_table = 'Direction' verbose_name = '方向(视频方向)' def __str__(self): return self.name # 视频分类 class Classification(models.Model): ''' 分类:Python,Linux,JavaScript,OpenStack,Node.js ''' name = models.CharField(verbose_name='名称', max_length=32) class Meta: db_table = 'Classification' verbose_name = '分类(视频分类)' def __str__(self): return self.name # 难度等级 class Level(models.Model): title = models.CharField(max_length=32) class Meta: verbose_name = '难度级别' def __str__(self): return self.title # 视频 class Video(models.Model): status_choice = ( (1, '下线'), (2, '上线'), ) status = models.IntegerField(verbose_name='状态', choices=status_choice, default=1) level = models.ForeignKey('Level', on_delete=models.CASCADE) classification = models.ForeignKey('Classification', null=True, blank=True, on_delete=models.CASCADE) weight = models.IntegerField(verbose_name='权重(按从大到小排列', default=0) title = models.CharField(verbose_name='标题', max_length=32) summary = models.CharField(verbose_name='简介', max_length=32) img = models.ImageField(verbose_name='图片', upload_to='./static/images/Video/') href = models.CharField(verbose_name='视频地址', max_length=256) create_date = models.DateTimeField(auto_now_add=True) class Meta: verbose_name = '视频' def __str__(self): return self.title
一对多的筛选:
URL:
re_path('video-(?P<classification_id>(\d+))-(?P<level_id>(\d+))-(?P<status>(\d+)).html/', views.video),
View:
def video(request, *args, **kwargs): # 创建一个空字典存放筛选信息 condition = { # 'level_id': 0, # 'classification_id': 0, } # 循环遍历传递过来的数据kwargs for k, v in kwargs.items(): # 字符串类型转数字类型 temp = int(v) # 更新kwargs字典 kwargs[k] = temp # 如果传递过来的是非0数字(若传过来的是0,则不筛选,显示全部) if temp: # 存放筛选信息 condition[k] = temp # 获取所有的视频分类 class_list = models.Classification.objects.all() # 获取所有的视频级别 level_list = models.Level.objects.all() # 获取所有的视频状态 status_list = list(map(lambda x: {'id': x[0], 'name': x[1]}, models.Video.status_choice)) # 获取符合筛选条件的视频列表 video_list = models.Video.objects.filter(**condition) return render( request, 'video.html', { 'class_list': class_list, 'level_list': level_list, 'status_list': status_list, 'kwargs': kwargs, 'video_list': video_list, } )
HTML
<style> .condition a{ display: inline-block; padding: 5px 8px; border: 1px solid #dddddd; } .condition a.active{ background-color: coral; color: white; } </style> <body> <div class="condition"> <h1>筛选条件</h1> {#筛选条件 - 分类#} <div> {% if kwargs.classification_id == 0 %} <a href="/video-0-{{ kwargs.level_id }}-{{ kwargs.status }}.html" class="active">全部</a> {% else %} <a href="/video-0-{{ kwargs.level_id }}-{{ kwargs.status }}.html">全部</a> {% endif %} {% for item in class_list %} {% if item.id == kwargs.classification_id %} <a href="/video-{{ item.id }}-{{ kwargs.level_id }}-{{ kwargs.status }}.html" class="active">{{ item.name }}</a> {% else %} <a href="/video-{{ item.id }}-{{ kwargs.level_id }}-{{ kwargs.status }}.html">{{ item.name }}</a> {% endif %} {% endfor %} </div> {#筛选条件 - 难度级别#} <div> {% if kwargs.level_id == 0 %} <a href="/video-{{ kwargs.classification_id }}-0-{{ kwargs.status }}.html" class="active">全部</a> {% else %} <a href="/video-{{ kwargs.classification_id }}-0-{{ kwargs.status }}.html">全部</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">{{ item.title }}</a> {% else %} <a href="/video-{{ kwargs.classification_id }}-{{ item.id }}-{{ kwargs.status }}.html">{{ item.title }}</a> {% endif %} {% endfor %} </div> {#筛选条件 - 上下线状态#} <div> {% if kwargs.status == 0 %} <a href="/video-{{ kwargs.classification_id }}-{{ kwargs.level_id }}-0.html" class="active">全部</a> {% else %} <a href="/video-{{ kwargs.classification_id }}-{{ kwargs.level_id }}-0.html">全部</a> {% endif %} {% for status in status_list %} {% if status.id == kwargs.status %} <a href="/video-{{ kwargs.classification_id }}-{{ kwargs.level_id }}-{{ status.id }}.html" class="active">{{ status.name }}</a> {% else %} <a href="/video-{{ kwargs.classification_id }}-{{ kwargs.level_id }}-{{ status.id }}.html">{{ status.name }}</a> {% endif %} {% endfor %} </div> </div> <div> <h1>筛选结果</h1> {% for video in video_list %} <div> {{ video.title }} </div> {% endfor %} </div> </body>
多对多的筛选:
URL
re_path('video2-(?P<direction_id>(\d+))-(?P<classification_id>(\d+))-(?P<level_id>(\d+)).html/', views.video2,name='video2'),
View:

''' 如果:方向direction_id = 0 即所有方向 则列出所有的分类 如果:分类classification_id = 0: 则列出所有的视频 如果:分类classification_id != 0: 则列出该类别的所有视频 condition['classification_id'] = classification_id 如果:方向direction_id !=0 即指定方向 则列出该方向下的所有分类 如果:分类classification_id = 0: 则列出该方向下的所有分类[1,2,3,4]的视频 condition['classification_id__in'] = [1,2,3,4] 如果:分类classification_id != 0: 获取当前方向下的所有分类[1,2,3,4] 判定classification_id是否在该方向下的所有分类中[1,2,3,4] 如果在: 则列出该方向下的该类别的所有视频 condition['classification_id'] = classification_id 如果不在: 则列出该方向下的所有类别的所有视频 condition['classification_id__in'] = [5,6] '''
def video2(request, *args, **kwargs): # 创建一个空字典存放筛选信息 condition = {} # 循环遍历传递过来的数据kwargs for k, v in kwargs.items(): # 字符串类型转数字类型 temp = int(v) # 更新kwargs字典 kwargs[k] = temp print(kwargs) # (?P<direction_id>(\d+))-(?P<classification_id>(\d+))-(?P<level_id>(\d+)) # 构造查询字典 # 从kwargs获取方向id、分类id、级别id direction_id = kwargs['direction_id'] classification_id = kwargs['classification_id'] level_id = kwargs['level_id'] # 获取所有的方向 direction_list = models.Direction.objects.all() # 如果方向id为0,则显示所有的分类 if direction_id == 0: # 获取所有的分类 class_list = models.Classification.objects.all() # 如果分类id为0,则不添加分类的筛选条件,显示所有的视频 if classification_id == 0: pass else: # 如果分类id不为0,则添加分类的筛选条件:classification_id,显示该分类id下的所有视频 condition['classification_id'] = classification_id # 如果方向id不为0,则显示特定方向的所有分类 else: # 获取特定的方向对象 QuerySet[obj] direction_obj = models.Direction.objects.filter(id=direction_id).first() # 获取特定方向下的所有分类对象 QuerySet[obj,...] class_list = direction_obj.classification.all() # 获取特定方向下的所有分类对象的id QuerySet[(id1,),(id2),...] classification_ids = direction_obj.classification.all().values_list('id') # 如果该特定方向下的分类对象为空 if not classification_ids: # 则类别筛选条件为空列表 classification_id_list = [] # 如果该特定方向下的分类对象不为空 else: # 将QuerySet[(id1,id2),...]转换为列表[(id1,id2,...)] # 则类别筛选条件为(id1,id2,...) classification_id_list = list(zip(*classification_ids))[0] # 如果类别为0 则显示特定方向的全部分类的所有视频 if classification_id == 0: # 添加类别筛选条件 condition['classification_id__in'] = classification_id_list # 如果类别不为0 else: # 如果当前类别id在变化后的类别id列表中 if classification_id in classification_id_list: # 选中当前的类别id condition['classification_id'] = classification_id # 如果当前类别id不在变化后的类别id列表中 else: # 给类别id赋值为0,即选中全部 kwargs['classification_id'] = 0 # 添加类别筛选条件 condition['classification_id__in'] = classification_id_list # 获取所有的级别对象 level_list = models.Level.objects.all() # 如果级别id为0,则不进行级别筛选,显示所有级别的视频 if level_id == 0: pass # 如果级别id不为0,则进行级别筛选,显示该级别的视频 else: # 添加级别筛选条件 condition['level_id'] = level_id # 按照上述所有的筛选条件进行视频筛选 video_list = models.Video.objects.filter(**condition) # models.Video.objects.filter() return render(request, 'video2.html', { 'direction_list': direction_list, 'class_list': class_list, 'level_list': level_list, 'video_list': video_list, 'kwargs': kwargs, })
HTML
{% include 'base.html' %} <style> .condition a{ display: inline-block; padding: 5px 8px; border: 1px solid #dddddd; } .condition a.active{ background-color: coral; color: white; } </style> <body> <div class="condition"> <h1>筛选条件</h1> {#筛选条件 - 方向#} <div> {% if kwargs.direction_id == 0 %} <a href="{% url 'video2' direction_id=0 classification_id=kwargs.classification_id level_id=kwargs.level_id %}" class="active">全部</a> {% else %} <a href="{% url 'video2' direction_id=0 classification_id=kwargs.classification_id level_id=kwargs.level_id %}" >全部</a> {% endif %} {% for item in direction_list %} {% if item.id == kwargs.direction_id %} <a href="{% url 'video2' direction_id=item.id classification_id=kwargs.classification_id level_id=kwargs.level_id %}" class="active">{{ item.name }}</a> {% else %} <a href="{% url 'video2' direction_id=item.id classification_id=kwargs.classification_id level_id=kwargs.level_id %}">{{ item.name }}</a> {% endif %} {% endfor %} </div> {#筛选条件 - 分类#} <div> {% if kwargs.classification_id == 0 %} <a href="{% url 'video2' direction_id=kwargs.direction_id classification_id=0 level_id=kwargs.level_id %}" class="active">全部</a> {% else %} <a href="{% url 'video2' direction_id=kwargs.direction_id classification_id=0 level_id=kwargs.level_id %}" >全部</a> {% endif %} {% for item in class_list %} {% if item.id == kwargs.classification_id %} <a href="{% url 'video2' direction_id=kwargs.direction_id classification_id=item.id level_id=kwargs.level_id %}" class="active">{{ item.name }}</a> {% else %} <a href="{% url 'video2' direction_id=kwargs.direction_id classification_id=item.id level_id=kwargs.level_id %}">{{ item.name }}</a> {% endif %} {% endfor %} </div> {#筛选条件 - 难度级别#} <div> {% if kwargs.level_id == 0 %} <a href="{% url 'video2' direction_id=kwargs.direction_id classification_id=kwargs.classification_id level_id=0 %}" class="active">全部</a> {% else %} <a href="{% url 'video2' direction_id=kwargs.direction_id classification_id=kwargs.classification_id level_id=0 %}" >全部</a> {% endif %} {% for item in level_list %} {% if item.id == kwargs.level_id %} <a href="{% url 'video2' direction_id=kwargs.direction_id classification_id=kwargs.classification_id level_id=item.id %}" class="active">{{ item.title }}</a> {% else %} <a href="{% url 'video2' direction_id=kwargs.direction_id classification_id=kwargs.classification_id level_id=item.id %}">{{ item.title }}</a> {% endif %} {% endfor %} </div> </div> <div> <h1>筛选结果</h1> {% for video in video_list %} <div>{{ video.title }}</div> {% endfor %} </div> </body>