【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\d+)-(?P\d+)-(?P\d+).html/$', views.video),
url('^video2-(?P\d+)-(?P\d+)-(?P\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
视频-组合筛选
筛选
编程语言分类:
{% if kwargs.classification_id == 0 %}
全部
{% else %}
全部
{% endif %}
{% for item in classification_list %}
{% if item.id == kwargs.classification_id %}
{{ item.name }}
{% else %}
{{ item.name }}
{% endif %}
{% endfor %}
难度等级:
{% if kwargs.level_id == 0 %}
全部
{% else %}
全部
{% endif %}
{% for item in level_list %}
{% if item.id == kwargs.level_id %}
{{ item.title }}
{% else %}
{{ item.title }}
{% endif %}
{% endfor %}
上线/下线:
{% if kwargs.status == 0 %}
全部
{% else %}
全部
{% endif %}
{% for item in status_list %}
{% if item.id == kwargs.status %}
{{ item.name }}
{% else %}
{{ item.name }}
{% endif %}
{% endfor %}
搜索结果
{% for video in video_list %}
标题: {{ video.title }}
简介: {{ video.summary }}
图片:
视频href: {{ video.href }}
{% endfor %}
版本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:
组合筛选2
筛选
视频方向:
{% if kwargs.direction_id == 0 %}
全部
{% else %}
全部
{% endif %}
{% for direction in direction_list %}
{% if kwargs.direction_id == direction.id %}
{{ direction.name }}
{% else %}
{{ direction.name }}
{% endif %}
{% endfor %}
语言分类:
{% if classification_id == 0 %}
全部
{% else %}
全部
{% endif %}
{% for item in classification_list %}
{% if classification_id == item.id %}
{{ item.name }}
{% else %}
{{ item.name }}
{% endif %}
{% endfor %}
难度等级:
{% if kwargs.level_id == 0 %}
全部
{% else %}
全部
{% endif %}
{% for item in level_list %}
{% if kwargs.level_id == item.id %}
{{ item.title }}
{% else %}
{{ item.title }}
{% endif %}
{% endfor %}
搜索结果
{% for video in video_list %}
标题: {{ video.title }}
简介: {{ video.summary }}
图片:
视频href: {{ video.href }}
{% endfor %}
重要知识点总结:
1、路由中正则使用有名分组,传入的信息以字典格式保存在 视图函数的 kwargs中
url('^video-(?P\d+)-(?P\d+)-(?P\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循环遍历
编程语言分类:
{% if kwargs.classification_id == 0 %} 全部 {% else %} 全部 {% endif %} {% for item in classification_list %} {% if item.id == kwargs.classification_id %} {{ item.name }} {% else %} {{ item.name }} {% endif %} {% endfor %}
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