Django 标签筛选的实现代码(一对多、多对多)


Posted in PHP onSeptember 05, 2018

实现的目标(一对多)

实现针对课程实现:课程类型、难度级别、是否隐藏三个方式的筛选

每一个视频文件有针对一个课程类型、一个难度级别、是否隐藏

设计数据库如下:

# 视频分类表格
class VideoType(models.Model):
 Video_Type = models.CharField(max_length=50)
 class Meta:
 verbose_name_plural = '视频分类'
 def __str__(self):
 return self.Video_Type
# 视频难度表格
class VideoDif(models.Model):
 Video_dif = models.CharField(max_length=50)
 class Meta:
 verbose_name_plural = '视频难度'
 def __str__(self):
 return self.Video_dif
# 视频:ID、视频图片、视频名称、视频简介、视频地址、视频分类、视频难度、权重、是否显示
class Video(models.Model):
 Video_img = models.CharField(max_length=100)
 Video_title = models.CharField(max_length=100)
 Video_text = models.TextField()
 Video_type_id = models.ForeignKey('VideoType', on_delete=models.CASCADE,)
 Video_dif_id = models.ForeignKey('VideoDif', on_delete=models.CASCADE,)
 Video_qz = models.IntegerField(default=0)
 display_choice = (
 (1, '显示'),
 (2, '隐藏'),
 )
 display = models.IntegerField(verbose_name='状态', choices=display_choice, default=1)
 class Meta:
 verbose_name_plural = '视频'

URL文件:

from django.urls import re_path
urlpatterns = [
 path('admin/', admin.site.urls),
 path('video/', views.video),
 # 通过正则表达式添加三个字段,从前台获取当前选择项
 re_path('video-(?P<Video_type_id>(\d+))-(?P<Video_dif_id>(\d+))-(?P<display>(\d+))', views.video),

后台程序文件:

def video(request,*args,**kwargs):
 # 给后台筛选数据库使用
 condition = {}
 # kwargs是从前台URL获取的键值对,如果第一次访问,针对字典做一个初始化
 if not kwargs:
 kwargs ={
  'Video_type_id':0,
  'Video_dif_id':0,
  'display':0,
 }
 # 依次取出kwargs字典中传来的值
 for k, v in kwargs.items():
 # 首先将传来的值变为数字类型
 temp = int(v)
 kwargs[k] = temp
 # 如果kwargs中有值,循环将值赋予condition列表
 if temp:
  condition[k] = temp
 # 从数据库中获取视频类型的列表
 VideoType_list = models.VideoType.objects.all()
 # 从数据库中获取视频难度的列表
 VideoDif_list = models.VideoDif.objects.all()
 # 从数据库中视频列表中,获取是否显示的字段的内容,是一个元组形式的:((1, '显示'), (2, '隐藏'))
 # map后形成一个map对象:{'id':1,'name':'显示'}
 # 最后list转换为列表:[{'id': 1, 'name': '显示'}, {'id': 2, 'name': '隐藏'}]
 display_list = list(map(lambda x:{'id':x[0],'name':x[1]},models.Video.display_choice))
 # 根据condition列表筛选数据库中的视频列表
 video_list = models.Video.objects.filter(**condition)
 return render(
 request,
 'video1.html',
 {
  'VideoType_list': VideoType_list,
  'VideoDif_list': VideoDif_list,
  'kwargs': kwargs,
  'video_list': video_list,
  'display_list': display_list,
 }
 )

前台展示文件:

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <title>Title</title>
 <style>
 .condition a{
  display: inline-block;;
  padding: 5px 8px;
  border: 1px solid #dddddd;
 }
 .condition a.active{
  background-color: red;
  color: white;
 }
 </style>
</head>
<body>
 <div class="condition">
 <h1>筛选</h1>
 <div>
  {% if kwargs.Video_type_id == 0%}
  <a href="/video-0-{{ kwargs.Video_dif_id }}-{{ kwargs.display }}" rel="external nofollow" rel="external nofollow" class="active">全部</a>
  {% else %}
  <a href="/video-0-{{ kwargs.Video_dif_id }}-{{ kwargs.display }}" rel="external nofollow" rel="external nofollow" >全部</a>
  {% endif %}
  {% for i in VideoType_list %}
  {% if i.id == kwargs.Video_type_id %}
   <a href="/video-{{ i.id }}-{{ kwargs.Video_dif_id }}-{{ kwargs.display }}" rel="external nofollow" rel="external nofollow" class="active">{{ i.Video_Type }}</a>
  {% else %}
   <a href="/video-{{ i.id }}-{{ kwargs.Video_dif_id }}-{{ kwargs.display }}" rel="external nofollow" rel="external nofollow" >{{ i.Video_Type }}</a>
  {% endif %}
  {% endfor %}
 </div>
 <div>
  {% if kwargs.Video_dif_id == 0%}
  <a href="/video-{{ kwargs.Video_type_id }}-0-{{ kwargs.display }}" rel="external nofollow" rel="external nofollow" class="active">全部</a>
  {% else %}
  <a href="/video-{{ kwargs.Video_type_id }}-0-{{ kwargs.display }}" rel="external nofollow" rel="external nofollow" >全部</a>
  {% endif %}
  {% for i in VideoDif_list %}
  {% if i.id == kwargs.Video_dif_id %}
   <a href="/video-{{ kwargs.Video_type_id }}-{{ i.id }}-{{ kwargs.display }}" rel="external nofollow" rel="external nofollow" class="active">{{ i.Video_dif }}</a>
  {% else %}
   <a href="/video-{{ kwargs.Video_type_id }}-{{ i.id }}-{{ kwargs.display }}" rel="external nofollow" rel="external nofollow" >{{ i.Video_dif }}</a>
  {% endif %}
  {% endfor %}
 </div>
 <div>
  {% if kwargs.display == 0 %}
  <a class="active" href="/video-{{ kwargs.Video_type_id }}-{{ kwargs.Video_dif_id }}-0" rel="external nofollow" rel="external nofollow" >全部</a>
  {% else %}
  <a href="/video-{{ kwargs.Video_type_id }}-{{ kwargs.Video_dif_id }}-0" rel="external nofollow" rel="external nofollow" >全部</a>
  {% endif %}
  {% for item in display_list %}
  {% if item.id == kwargs.display %}
   <a class="active" href="/video-{{ kwargs.Video_type_id }}-{{ kwargs.Video_dif_id }}-{{ item.id }}" rel="external nofollow" rel="external nofollow" >{{ item.name }}</a>
  {% else %}
   <a href="/video-{{ kwargs.Video_type_id }}-{{ kwargs.Video_dif_id }}-{{ item.id }}" rel="external nofollow" rel="external nofollow" >{{ item.name }}</a>
  {% endif %}
  {% endfor %}
 </div>
 </div>
 <div>
 <h1>结果</h1>
 <div>
  {% for row in video_list %}
  <p>{{ row.Video_title }}</p>
  {% endfor %}
 </div>
 </div>
</body>
</html>

前台通过变化active标签,实现选中的显示,通过a标签中的数字控制后台筛选操作

实现的目标(多对多)

实现针对课程实现:课程方向、课程类型、难度级别三个方式的筛选

其中每个课程方向中包含有多个课程类型,选择课程方向后,筛选课程方向包含的所有课程类型

每一个视频文件有针对一个课程类型、一个难度级别

设计数据库如下,在一对多的基础上增加了一个多对多的课程方向表:

# 方向分类:ID、名称(与视频—分类做多对多关系)
class VideoGroup(models.Model):
 Video_group = models.CharField(max_length=50)
 group_type = models.ManyToManyField('VideoType')
 class Meta:
 verbose_name_plural = '方向分类'
 def __str__(self):
 return self.Video_group
# 视频分类表格
class VideoType(models.Model):
 Video_Type = models.CharField(max_length=50)
 class Meta:
 verbose_name_plural = '视频分类'
 def __str__(self):
 return self.Video_Type
# 视频难度表格
class VideoDif(models.Model):
 Video_dif = models.CharField(max_length=50)
 class Meta:
 verbose_name_plural = '视频难度'
 def __str__(self):
 return self.Video_dif
# 视频:ID、视频图片、视频名称、视频简介、视频地址、视频分类、视频难度、权重、是否显示
class Video(models.Model):
 Video_img = models.CharField(max_length=100)
 Video_title = models.CharField(max_length=100)
 Video_text = models.TextField()
 Video_type_id = models.ForeignKey('VideoType', on_delete=models.CASCADE,)
 Video_dif_id = models.ForeignKey('VideoDif', on_delete=models.CASCADE,)
 Video_qz = models.IntegerField(default=0)
 display_choice = (
 (1, '显示'),
 (2, '隐藏'),
 )
 display = models.IntegerField(verbose_name='状态', choices=display_choice, default=1)
 class Meta:
 verbose_name_plural = '视频'

URL文件:

urlpatterns = [
 path('admin/', admin.site.urls),
 path('video2/', views.video2),
 re_path('video2-(?P<Video_group_id>(\d+))-(?P<Video_type_id>(\d+))-(?P<Video_dif_id>(\d+))', views.video2),
]

后台程序文件:

def video2(request, *args, **kwargs):
 condition = {}
 # 思路 -- 构造查询字典
 """
 如果:获取Video_group_id=0 代表方向是全部,不会对以后的筛选造成影响
 *列出所有的type
 如果:Video_type_id=0
  pass
 否则:
  condition【'Video_type_id'】= Video_type_id
 否则:*列出当前方向下的type
 如果:Video_type_id=0
  获取当前方向下的type的所有的id【1,2,3,4】
  condition【'Video_type_id__in'】= 【1,2,3,4】
 否则:
  需要查看当前的type是否在当前的方向列表中,如果在:
  condition【'Video_type_id'】= Video_type_id
  如果不在:
  condition【'Video_type_id__in'】= 【1,2,3,4】
 """
 if not kwargs:
 kwargs = {
  'Video_type_id':0,
  'Video_dif_id':0,
  'Video_group_id':0,
 }
 for k, v in kwargs.items():
 temp = int(v)
 kwargs[k] = temp
 # 首先从kwargs中取出相应的id
 group_id = kwargs.get('Video_group_id')
 type_id = kwargs.get('Video_type_id')
 dif_id = kwargs.get('Video_dif_id')
 # 从数据库中取出所有的group列表,因为所有方向在页面上都要显示
 group_list = models.VideoGroup.objects.all()
 # 判断group值是否为0
 if group_id == 0:
 # 如果为0,则列出所有type的列表
 VideoType_list = models.VideoType.objects.all()
 # 如果type的列表也为0,筛选中就不用作特殊操作
 if type_id == 0:
  pass
 # 如果type的列表不为0,筛选列表中增加type的id
 else:
  condition['Video_type_id'] = type_id
 # 如果group值不为0
 else:
 # 首先根据group的id筛选出分类表格中的内容,形成一个对象
 group_obj = models.VideoGroup.objects.filter(id=group_id).first()
 # 再根据group筛选出的对象,用多对多表格字段,筛选出所有的type的列表,等待返回给前台使用
 VideoType_list = group_obj.group_type.all()
 # 获取筛选后的type的id值,得到一个QuerySet [(1,),(3,),(4,)]的对象
 vlist = group_obj.group_type.all().values_list('id')
 # 如果筛选后的type的值为空,也就是没有找到对应的type类型
 if not vlist:
  # 设置一个空列表
  type_ids = []
 # 如果筛选后的type值有内容
 else:
  # 将vlist进行一个zip,获得一个zip的对象,再转化为列表,得到一个【(1,3,4)】,取第一个值,得到(1,3,4)
  type_ids = list(zip(*vlist))[0] # (1,3,4)
 # 判断如果前台传来的type为0的话
 if type_id == 0:
  # 后台筛选的时候,查询按照方向筛选出来的type_ids进行查询
  # __in指的是用列表方式查询多个id
  condition['Video_type_id__in'] = type_ids
 # 如果前台传来的type不为0的时候,有两种情况
 else:
  # 如果前台传来的type值在后台筛选的值范围内的时候
  if type_id in type_ids:
  # 后台筛选的typeid就按照前台传来的type值筛选,也就是前台选了某个课程,如果课程方向发生改变的时候,课程类型还在选择范围内,前台也仍然是选中的状态,我们也就仍然返回选中的课程类型筛选的内容
  condition['Video_type_id'] = type_id
  # 如果前台传来的type值不在后台筛选的值范围内的时候
  else:
  # 就按照后台筛选的课程方向向下的所有type类型进行筛选
  condition['Video_type_id__in'] = type_ids
  kwargs['Video_type_id'] = 0
 # 难度这边跟上面的多对多没有关联,与一对多的情况时一样
 if dif_id == 0:
 pass
 else:
 condition['Video_dif_id'] = dif_id
 VideoDif_list = models.VideoDif.objects.all()
 # 最终将符合条件的视频筛选出来
 video_list = models.Video.objects.filter(**condition)
 return render(
 request,
 'video2.html',
 {
  'group_list': group_list,
  'VideoType_list': VideoType_list,
  'VideoDif_list': VideoDif_list,
  'video_list': video_list,
  'kwargs': kwargs
 }
 )

前台展示文件:

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <title>Title</title>
 <style>
 .condition a{
  display: inline-block;;
  padding: 5px 8px;
  border: 1px solid #dddddd;
 }
 .condition a.active{
  background-color: red;
  color: white;
 }
 </style>
</head>
<body>
 <div class="condition">
 <h1>筛选</h1>
 <div>
  {% if kwargs.Video_group_id == 0%}
  <a href="/video2-0-{{ kwargs.Video_type_id }}-{{ kwargs.Video_dif_id }}" rel="external nofollow" rel="external nofollow" class="active">全部</a>
  {% else %}
  <a href="/video2-0-{{ kwargs.Video_type_id }}-{{ kwargs.Video_dif_id }}" rel="external nofollow" rel="external nofollow" >全部</a>
  {% endif %}
  {% for item in group_list %}
  {% if item.id == kwargs.Video_group_id %}
   <a class="active" href="/video2-{{ item.id }}-{{ kwargs.Video_type_id }}-{{ kwargs.Video_dif_id }}" rel="external nofollow" rel="external nofollow" >{{ item.Video_group }}</a>
  {% else %}
   <a href="/video2-{{ item.id }}-{{ kwargs.Video_type_id }}-{{ kwargs.Video_dif_id }}" rel="external nofollow" rel="external nofollow" >{{ item.Video_group }}</a>
  {% endif %}
  {% endfor %}
 </div>
 <div>
  {% if kwargs.Video_type_id == 0%}
  <a href="/video2-{{ kwargs.Video_group_id }}-0-{{ kwargs.Video_dif_id }}" rel="external nofollow" rel="external nofollow" class="active">全部</a>
  {% else %}
  <a href="/video2-{{ kwargs.Video_group_id }}-0-{{ kwargs.Video_dif_id }}" rel="external nofollow" rel="external nofollow" >全部</a>
  {% endif %}
  {% for item in VideoType_list %}
  {% if item.id == kwargs.Video_type_id %}
   <a class="active" href="/video2-{{ kwargs.Video_group_id }}-{{ item.id }}-{{ kwargs.Video_dif_id }}" rel="external nofollow" rel="external nofollow" >{{ item.Video_Type }}</a>
  {% else %}
   <a href="/video2-{{ kwargs.Video_group_id }}-{{ item.id }}-{{ kwargs.Video_dif_id }}" rel="external nofollow" rel="external nofollow" >{{ item.Video_Type }}</a>
  {% endif %}
  {% endfor %}
 </div>
 <div>
  {% if kwargs.Video_dif_id == 0%}
  <a href="/video2-{{ kwargs.Video_group_id }}-{{ kwargs.Video_type_id }}-0" rel="external nofollow" rel="external nofollow" class="active">全部</a>
  {% else %}
  <a href="/video2-{{ kwargs.Video_group_id }}-{{ kwargs.Video_type_id }}-0" rel="external nofollow" rel="external nofollow" >全部</a>
  {% endif %}
  {% for item in VideoDif_list %}
  {% if item.id == kwargs.Video_dif_id %}
   <a class="active" href="/video2-{{ kwargs.Video_group_id }}-{{ kwargs.Video_type_id }}-{{ item.id }}" rel="external nofollow" rel="external nofollow" >{{ item.Video_dif }}</a>
  {% else %}
   <a href="/video2-{{ kwargs.Video_group_id }}-{{ kwargs.Video_type_id }}-{{ item.id }}" rel="external nofollow" rel="external nofollow" >{{ item.Video_dif }}</a>
  {% endif %}
  {% endfor %}
 </div>
 </div>
 <div>
 <h1>结果</h1>
 <div>
  {% for item in video_list %}
  <p>{{ item.Video_title }}</p>
  {% endfor %}
 </div>
 </div>
</body>
</html>

总结

以上所述是小编给大家介绍的Django 标签筛选的实现代码(一对多、多对多),希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

PHP 相关文章推荐
提升PHP执行速度全攻略(下)
Oct 09 PHP
用PHP和ACCESS写聊天室(四)
Oct 09 PHP
Admin generator, filters and I18n
Oct 06 PHP
PHP exif扩展方法开启详解
Jul 28 PHP
刷新PHP缓冲区为你的站点加速
Oct 10 PHP
Yii2 assets清除缓存的方法
May 16 PHP
基于PHP实现数据分页显示功能
May 26 PHP
windows server 2008/2012安装php iis7 mysql环境搭建教程
Jun 30 PHP
php实现通过soap调用.Net的WebService asmx文件
Feb 27 PHP
利用PHP判断是否是连乘数字串的方法示例
Jul 03 PHP
PDO::quote讲解
Jan 29 PHP
Laravel 实现数据软删除功能
Aug 21 PHP
利用PHP扩展Xhprof分析项目性能实践教程
Sep 05 #PHP
PHP时间处理类操作示例
Sep 05 #PHP
PHP命名空间与自动加载类详解
Sep 04 #PHP
ThinkPHP框架实现定时执行任务的两种方法分析
Sep 04 #PHP
php 后端实现JWT认证方法示例
Sep 04 #PHP
PHP利用Mysql锁解决高并发的方法
Sep 04 #PHP
TP5(thinkPHP5)框架基于ajax与后台数据交互操作简单示例
Sep 03 #PHP
You might like
PHP资源管理框架Assetic简介
2014/06/12 PHP
CI框架整合smarty步骤详解
2016/05/19 PHP
php实现的pdo公共类定义与用法示例
2017/07/19 PHP
PHP实现打包下载文件的方法示例
2017/10/07 PHP
Laravel 实现Controller向blade前台模板赋值的四种方式小结
2019/10/22 PHP
jquery tab插件制作实现代码
2010/06/22 Javascript
javascript数据结构之二叉搜索树实现方法
2015/11/25 Javascript
基于javascript实现浏览器滚动条快到底部时自动加载数据
2015/11/30 Javascript
javascript 用函数实现继承详解
2016/05/28 Javascript
基于MVC5和Bootstrap的jQuery TreeView树形控件(一)之数据支持json字符串、list集合
2016/08/11 Javascript
详解Vue 中 extend 、component 、mixins 、extends 的区别
2017/12/20 Javascript
Vue2.X 通过AJAX动态更新数据
2018/07/17 Javascript
React 源码中的依赖注入方法
2018/11/07 Javascript
vue中如何实现后台管理系统的权限控制的方法步骤
2019/09/05 Javascript
编写Python的web框架中的Model的教程
2015/04/29 Python
利用Python自动监控网站并发送邮件告警的方法
2016/08/24 Python
Python对象转换为json的方法步骤
2019/04/25 Python
Django错误:TypeError at / 'bool' object is not callable解决
2019/08/16 Python
Python aiohttp百万并发极限测试实例分析
2019/10/26 Python
Django中的session用法详解
2020/03/09 Python
Django xadmin安装及使用详解
2020/10/26 Python
CSS3中的@keyframes关键帧动画的选择器绑定
2016/06/13 HTML / CSS
Stuart Weitzman欧盟:美国奢华鞋履品牌
2017/05/24 全球购物
铭立家具面试题
2012/12/06 面试题
中专生自我鉴定范文
2013/12/19 职场文书
解除劳动合同协议书范本
2014/04/14 职场文书
租房协议书样本
2014/08/20 职场文书
2014大学生中国梦主题教育学习思想汇报
2014/09/10 职场文书
2014最新房贷收入证明范本
2014/09/12 职场文书
单位委托书
2014/10/15 职场文书
2014年师德师风工作总结
2014/11/25 职场文书
综合素质评价个性与发展自我评价
2015/03/06 职场文书
心理健康教育培训研修感言
2015/11/18 职场文书
68句权威创业名言
2019/08/26 职场文书
导游词之广州陈家祠
2019/10/21 职场文书
如何用Python搭建gRPC服务
2021/06/30 Python