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

实现的目标(一对多)

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

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

设计数据库如下:

# 视频分类表格

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 标签筛选的实现代码(一对多、多对多),希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对网站的支持!

以上是 Django 标签筛选的实现代码(一对多、多对多) 的全部内容, 来源链接: www.h5w3.com/222206.html

回到顶部