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 相关文章推荐
BBS(php &amp; mysql)完整版(四)
Oct 09 PHP
访问编码后的中文URL返回404错误的解决方法
Aug 20 PHP
PHP实现自动识别Restful API的返回内容类型
Feb 07 PHP
php+ajax无刷新分页实例详解
Dec 07 PHP
WordPress中访客登陆实现邮件提醒的PHP脚本实例分享
Dec 14 PHP
yii2框架中使用下拉菜单的自动搜索yii-widget-select2实例分析
Jan 09 PHP
ThinkPHP和UCenter接口冲突的解决方法
Jul 25 PHP
PHP类型约束用法示例
Sep 28 PHP
PHP explode()函数用法讲解
Feb 15 PHP
浅谈PHP无限极分类原理
Mar 14 PHP
php curl操作API接口类完整示例
May 21 PHP
php实现图片压缩处理
Sep 09 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获取谷歌PR值算法,附上php查询PR值代码示例
2011/12/25 PHP
PHP中使用php://input处理相同name值的表单数据
2015/02/03 PHP
PHP编程实现微信企业向用户付款的方法示例
2017/07/26 PHP
妙用Jquery的val()方法
2012/06/27 Javascript
ajax不执行success回调而是执行了error回调
2012/12/10 Javascript
hover的用法及live的用法介绍(鼠标悬停效果)
2013/03/29 Javascript
一个简单的jQuery计算器实现了连续计算功能
2014/07/21 Javascript
js面向对象之静态方法和静态属性实例分析
2015/01/10 Javascript
基于Jquery easyui 选中特定的tab
2015/11/17 Javascript
基于Jquery代码实现支持PC端手机端幻灯片代码
2015/11/17 Javascript
js带闹铃功能的倒计时代码
2016/09/29 Javascript
微信小程序 教程之事件
2016/10/18 Javascript
javascript编程实现栈的方法详解【经典数据结构】
2017/04/11 Javascript
详解Vue路由开启keep-alive时的注意点
2017/06/20 Javascript
JS简单实现数组去重的方法分析
2017/10/14 Javascript
为输入框加入数字js校验代码分享
2017/11/02 Javascript
详解npm 配置项registry修改为淘宝镜像
2018/09/07 Javascript
layui 点击重置按钮, select 并没有被重置的解决方法
2019/09/03 Javascript
详解JavaScript的this指向和绑定
2020/09/08 Javascript
Python实现HTTP协议下的文件下载方法总结
2016/04/20 Python
使用rst2pdf实现将sphinx生成PDF
2016/06/07 Python
python中urlparse模块介绍与使用示例
2017/11/19 Python
Python设计模式之代理模式实例详解
2019/01/19 Python
基于python实现查询ip地址来源
2020/06/02 Python
django中ImageField的使用详解
2020/12/21 Python
使用html5新特性轻松监听任何App自带返回键的示例
2018/03/13 HTML / CSS
惠普加拿大在线商店:HP加拿大
2017/09/15 全球购物
mysql的最长数据库名,表名,字段名可以是多长
2014/04/21 面试题
放飞蜻蜓反思
2014/02/05 职场文书
酒店管理专业毕业生自我鉴定
2014/09/29 职场文书
护士个人总结范文
2015/02/13 职场文书
房地产工程部经理岗位职责
2015/04/09 职场文书
职位证明模板
2015/06/23 职场文书
python scipy 稀疏矩阵的使用说明
2021/05/26 Python
MySQL8.0无法启动3534的解决方法
2021/06/03 MySQL
详解Java实践之抽象工厂模式
2021/06/18 Java/Android