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
View Code
一对多的筛选:
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>