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遍历数组的几种方法
Mar 22 PHP
php 函数中使用static的说明
Jun 01 PHP
php面向对象 字段的声明与使用
Jun 14 PHP
基于php iconv函数的使用详解
Jun 09 PHP
PHP json_encode中文乱码问题的解决办法
Sep 09 PHP
PHP分页详细讲解(有实例)
Oct 30 PHP
php合并js请求的例子
Nov 01 PHP
PHP根据IP判断地区名信息的示例代码
Mar 03 PHP
php实现数组中索引关联数据转换成json对象的方法
Jul 08 PHP
PHP下的浮点运算不准的解决方法
Oct 27 PHP
yii2多图上传组件的使用教程
May 10 PHP
Laravel框架实现定时Task Scheduling例子
Oct 22 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
图书管理程序(一)
2006/10/09 PHP
php使用pear_smtp发送邮件
2016/04/15 PHP
PHPCMS忘记后台密码的解决办法
2016/10/30 PHP
EXTjs4.0的store的findRecord的BUG演示代码
2013/06/08 Javascript
Bootstrap每天必学之栅格系统(布局)
2015/11/25 Javascript
JS与jQuery遍历Table所有单元格内容的方法
2015/12/07 Javascript
基于jQuery实现中英文切换导航条效果
2016/09/18 Javascript
使用JS正则表达式 替换括号,尖括号等
2016/11/29 Javascript
vue.js父组件使用外部对象的方法示例
2017/04/25 Javascript
javascript 日期相减-在线教程(附代码)
2017/08/17 Javascript
使用JQ完成表格隔行换色的简单实例
2017/08/25 Javascript
微信小程序之蓝牙的链接
2017/09/26 Javascript
实现div滚动条默认最底部以及默认最右边的示例代码
2017/11/15 Javascript
浅析前端路由简介以及vue-router实现原理
2018/06/01 Javascript
微信小程序自定义组件封装及父子间组件传值的方法
2018/08/28 Javascript
js实现json数组分组合并操作示例
2019/02/12 Javascript
vue $mount 和 el的区别说明
2020/09/11 Javascript
vuex的使用和简易实现
2021/01/07 Vue.js
详解python的几种标准输出重定向方式
2016/08/15 Python
python使用pyqt写带界面工具的示例代码
2017/10/23 Python
python3+PyQt5+Qt Designer实现扩展对话框
2018/04/20 Python
pycharm 将django中多个app放到同个文件夹apps的处理方法
2018/05/30 Python
python实现点对点聊天程序
2018/07/28 Python
Python3随机漫步生成数据并绘制
2018/08/27 Python
几行Python代码爬取3000+上市公司的信息
2019/01/24 Python
python set集合使用方法解析
2019/11/05 Python
python 在sql语句中使用%s,%d,%f说明
2020/06/06 Python
英国和世界各地鲜花速递专家:Arena Flowers
2018/02/10 全球购物
营销专业应届生求职信
2013/11/26 职场文书
《湘夫人》教学反思
2014/02/21 职场文书
置业顾问岗位职责
2014/03/02 职场文书
预防传染病方案
2014/06/14 职场文书
德育标兵事迹材料
2014/08/24 职场文书
普通党员自我剖析材料
2014/10/07 职场文书
同意迁入证明模板
2014/10/26 职场文书
PostgreSQL解析URL的方法
2021/08/02 PostgreSQL