侯体宗的博客
  • 首页
  • Hyperf版
  • beego仿版
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

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

框架(架构)  /  管理员 发布于 7年前   137

实现的目标(一对多)

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

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

设计数据库如下:

# 视频分类表格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_pathurlpatterns = [ path('admin/', admin.site.urls), path('video/', views.video), # 通过正则表达式添加三个字段,从前台获取当前选择项 re_path('video-(?P(\d+))-(?P(\d+))-(?P(\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, } )

前台展示文件:

  Title  

筛选

{% if kwargs.Video_type_id == 0%} 全部 {% else %} 全部 {% endif %} {% for i in VideoType_list %} {% if i.id == kwargs.Video_type_id %} {{ i.Video_Type }} {% else %} {{ i.Video_Type }} {% endif %} {% endfor %} {% if kwargs.Video_dif_id == 0%} 全部 {% else %} 全部 {% endif %} {% for i in VideoDif_list %} {% if i.id == kwargs.Video_dif_id %} {{ i.Video_dif }} {% else %} {{ i.Video_dif }} {% endif %} {% endfor %} {% if kwargs.display == 0 %} 全部 {% else %} 全部 {% endif %} {% for item in display_list %} {% if item.id == kwargs.display %} {{ item.name }} {% else %} {{ item.name }} {% endif %} {% endfor %}

结果

{% for row in video_list %}

{{ row.Video_title }}

{% endfor %}

前台通过变化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(\d+))-(?P(\d+))-(?P(\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 } )

前台展示文件:

  Title  

筛选

{% if kwargs.Video_group_id == 0%} 全部 {% else %} 全部 {% endif %} {% for item in group_list %} {% if item.id == kwargs.Video_group_id %} {{ item.Video_group }} {% else %} {{ item.Video_group }} {% endif %} {% endfor %} {% if kwargs.Video_type_id == 0%} 全部 {% else %} 全部 {% endif %} {% for item in VideoType_list %} {% if item.id == kwargs.Video_type_id %} {{ item.Video_Type }} {% else %} {{ item.Video_Type }} {% endif %} {% endfor %} {% if kwargs.Video_dif_id == 0%} 全部 {% else %} 全部 {% endif %} {% for item in VideoDif_list %} {% if item.id == kwargs.Video_dif_id %} {{ item.Video_dif }} {% else %} {{ item.Video_dif }} {% endif %} {% endfor %}

结果

{% for item in video_list %}

{{ item.Video_title }}

{% endfor %}

总结

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

您可能感兴趣的文章:

  • Django ManyToManyField 跨越中间表查询的方法
  • django多文件上传,form提交,多对多外键保存的实例
  • 基于Django ORM、一对一、一对多、多对多的全面讲解
  • django多对多表的创建,级联删除及手动创建第三张表
  • django数据关系一对多、多对多模型、自关联的建立
  • Django之多对多查询与操作方法详解
  • Django中数据库的数据关系:一对一,一对多,多对多
  • Django的数据模型访问多对多键值的方法
  • django ManyToManyField多对多关系的实例详解


  • 上一条:
    django中的ajax组件教程详解
    下一条:
    Django中通过定时任务触发页面静态化的处理方式
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • Filament v3.1版本发布(0个评论)
    • docker + gitea搭建一个git服务器流程步骤(0个评论)
    • websocket的三种架构方式使用优缺点浅析(0个评论)
    • ubuntu20.4系统中宿主机安装nginx服务,docker容器中安装php8.2实现运行laravel10框架网站(0个评论)
    • phpstudy_pro(小皮面板)中安装最新php8.2.9版本流程步骤(0个评论)
    • 近期文章
    • 在go中实现一个常用的先进先出的缓存淘汰算法示例代码(0个评论)
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(0个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 欧盟关于强迫劳动的规定的官方举报渠道及官方举报网站(0个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf文件功能(0个评论)
    • Laravel从Accel获得5700万美元A轮融资(0个评论)
    • 在go + gin中gorm实现指定搜索/区间搜索分页列表功能接口实例(0个评论)
    • 在go语言中实现IP/CIDR的ip和netmask互转及IP段形式互转及ip是否存在IP/CIDR(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2018-05
    • 2020-02
    • 2020-03
    • 2020-05
    • 2020-06
    • 2020-07
    • 2020-08
    • 2020-11
    • 2021-03
    • 2021-09
    • 2021-10
    • 2021-11
    • 2022-01
    • 2022-02
    • 2022-03
    • 2022-08
    • 2023-08
    • 2023-10
    • 2023-12
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客