實(shí)現(xiàn)的目標(biāo)(一對(duì)多)
實(shí)現(xiàn)針對(duì)課程實(shí)現(xiàn):課程類(lèi)型、難度級(jí)別、是否隱藏三個(gè)方式的篩選
每一個(gè)視頻文件有針對(duì)一個(gè)課程類(lèi)型、一個(gè)難度級(jí)別、是否隱藏
設(shè)計(jì)數(shù)據(jù)庫(kù)如下:
# 視頻分類(lèi)表格
class VideoType(models.Model):
Video_Type = models.CharField(max_length=50)
class Meta:
verbose_name_plural = '視頻分類(lèi)'
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、視頻圖片、視頻名稱(chēng)、視頻簡(jiǎn)介、視頻地址、視頻分類(lèi)、視頻難度、權(quán)重、是否顯示
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='狀態(tài)', 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),
# 通過(guò)正則表達(dá)式添加三個(gè)字段,從前臺(tái)獲取當(dāng)前選擇項(xiàng)
re_path('video-(?PVideo_type_id>(\d+))-(?PVideo_dif_id>(\d+))-(?Pdisplay>(\d+))', views.video),
后臺(tái)程序文件:
def video(request,*args,**kwargs):
# 給后臺(tái)篩選數(shù)據(jù)庫(kù)使用
condition = {}
# kwargs是從前臺(tái)URL獲取的鍵值對(duì),如果第一次訪問(wèn),針對(duì)字典做一個(gè)初始化
if not kwargs:
kwargs ={
'Video_type_id':0,
'Video_dif_id':0,
'display':0,
}
# 依次取出kwargs字典中傳來(lái)的值
for k, v in kwargs.items():
# 首先將傳來(lái)的值變?yōu)閿?shù)字類(lèi)型
temp = int(v)
kwargs[k] = temp
# 如果kwargs中有值,循環(huán)將值賦予condition列表
if temp:
condition[k] = temp
# 從數(shù)據(jù)庫(kù)中獲取視頻類(lèi)型的列表
VideoType_list = models.VideoType.objects.all()
# 從數(shù)據(jù)庫(kù)中獲取視頻難度的列表
VideoDif_list = models.VideoDif.objects.all()
# 從數(shù)據(jù)庫(kù)中視頻列表中,獲取是否顯示的字段的內(nèi)容,是一個(gè)元組形式的:((1, '顯示'), (2, '隱藏'))
# map后形成一個(gè)map對(duì)象:{'id':1,'name':'顯示'}
# 最后list轉(zhuǎn)換為列表:[{'id': 1, 'name': '顯示'}, {'id': 2, 'name': '隱藏'}]
display_list = list(map(lambda x:{'id':x[0],'name':x[1]},models.Video.display_choice))
# 根據(jù)condition列表篩選數(shù)據(jù)庫(kù)中的視頻列表
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,
}
)
前臺(tái)展示文件:
!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>結(jié)果/h1>
div>
{% for row in video_list %}
p>{{ row.Video_title }}/p>
{% endfor %}
/div>
/div>
/body>
/html>
前臺(tái)通過(guò)變化active標(biāo)簽,實(shí)現(xiàn)選中的顯示,通過(guò)a標(biāo)簽中的數(shù)字控制后臺(tái)篩選操作
實(shí)現(xiàn)的目標(biāo)(多對(duì)多)
實(shí)現(xiàn)針對(duì)課程實(shí)現(xiàn):課程方向、課程類(lèi)型、難度級(jí)別三個(gè)方式的篩選
其中每個(gè)課程方向中包含有多個(gè)課程類(lèi)型,選擇課程方向后,篩選課程方向包含的所有課程類(lèi)型
每一個(gè)視頻文件有針對(duì)一個(gè)課程類(lèi)型、一個(gè)難度級(jí)別
設(shè)計(jì)數(shù)據(jù)庫(kù)如下,在一對(duì)多的基礎(chǔ)上增加了一個(gè)多對(duì)多的課程方向表:
# 方向分類(lèi):ID、名稱(chēng)(與視頻—分類(lèi)做多對(duì)多關(guān)系)
class VideoGroup(models.Model):
Video_group = models.CharField(max_length=50)
group_type = models.ManyToManyField('VideoType')
class Meta:
verbose_name_plural = '方向分類(lèi)'
def __str__(self):
return self.Video_group
# 視頻分類(lèi)表格
class VideoType(models.Model):
Video_Type = models.CharField(max_length=50)
class Meta:
verbose_name_plural = '視頻分類(lèi)'
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、視頻圖片、視頻名稱(chēng)、視頻簡(jiǎn)介、視頻地址、視頻分類(lèi)、視頻難度、權(quán)重、是否顯示
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='狀態(tài)', choices=display_choice, default=1)
class Meta:
verbose_name_plural = '視頻'
URL文件:
urlpatterns = [
path('admin/', admin.site.urls),
path('video2/', views.video2),
re_path('video2-(?PVideo_group_id>(\d+))-(?PVideo_type_id>(\d+))-(?PVideo_dif_id>(\d+))', views.video2),
]
后臺(tái)程序文件:
def video2(request, *args, **kwargs):
condition = {}
# 思路 -- 構(gòu)造查詢(xún)字典
"""
如果:獲取Video_group_id=0 代表方向是全部,不會(huì)對(duì)以后的篩選造成影響
*列出所有的type
如果:Video_type_id=0
pass
否則:
condition【'Video_type_id'】= Video_type_id
否則:*列出當(dāng)前方向下的type
如果:Video_type_id=0
獲取當(dāng)前方向下的type的所有的id【1,2,3,4】
condition【'Video_type_id__in'】= 【1,2,3,4】
否則:
需要查看當(dāng)前的type是否在當(dāng)前的方向列表中,如果在:
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中取出相應(yīng)的id
group_id = kwargs.get('Video_group_id')
type_id = kwargs.get('Video_type_id')
dif_id = kwargs.get('Video_dif_id')
# 從數(shù)據(jù)庫(kù)中取出所有的group列表,因?yàn)樗蟹较蛟陧?yè)面上都要顯示
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:
# 首先根據(jù)group的id篩選出分類(lèi)表格中的內(nèi)容,形成一個(gè)對(duì)象
group_obj = models.VideoGroup.objects.filter(id=group_id).first()
# 再根據(jù)group篩選出的對(duì)象,用多對(duì)多表格字段,篩選出所有的type的列表,等待返回給前臺(tái)使用
VideoType_list = group_obj.group_type.all()
# 獲取篩選后的type的id值,得到一個(gè)QuerySet [(1,),(3,),(4,)]的對(duì)象
vlist = group_obj.group_type.all().values_list('id')
# 如果篩選后的type的值為空,也就是沒(méi)有找到對(duì)應(yīng)的type類(lèi)型
if not vlist:
# 設(shè)置一個(gè)空列表
type_ids = []
# 如果篩選后的type值有內(nèi)容
else:
# 將vlist進(jìn)行一個(gè)zip,獲得一個(gè)zip的對(duì)象,再轉(zhuǎn)化為列表,得到一個(gè)【(1,3,4)】,取第一個(gè)值,得到(1,3,4)
type_ids = list(zip(*vlist))[0] # (1,3,4)
# 判斷如果前臺(tái)傳來(lái)的type為0的話
if type_id == 0:
# 后臺(tái)篩選的時(shí)候,查詢(xún)按照方向篩選出來(lái)的type_ids進(jìn)行查詢(xún)
# __in指的是用列表方式查詢(xún)多個(gè)id
condition['Video_type_id__in'] = type_ids
# 如果前臺(tái)傳來(lái)的type不為0的時(shí)候,有兩種情況
else:
# 如果前臺(tái)傳來(lái)的type值在后臺(tái)篩選的值范圍內(nèi)的時(shí)候
if type_id in type_ids:
# 后臺(tái)篩選的typeid就按照前臺(tái)傳來(lái)的type值篩選,也就是前臺(tái)選了某個(gè)課程,如果課程方向發(fā)生改變的時(shí)候,課程類(lèi)型還在選擇范圍內(nèi),前臺(tái)也仍然是選中的狀態(tài),我們也就仍然返回選中的課程類(lèi)型篩選的內(nèi)容
condition['Video_type_id'] = type_id
# 如果前臺(tái)傳來(lái)的type值不在后臺(tái)篩選的值范圍內(nèi)的時(shí)候
else:
# 就按照后臺(tái)篩選的課程方向向下的所有type類(lèi)型進(jìn)行篩選
condition['Video_type_id__in'] = type_ids
kwargs['Video_type_id'] = 0
# 難度這邊跟上面的多對(duì)多沒(méi)有關(guān)聯(lián),與一對(duì)多的情況時(shí)一樣
if dif_id == 0:
pass
else:
condition['Video_dif_id'] = dif_id
VideoDif_list = models.VideoDif.objects.all()
# 最終將符合條件的視頻篩選出來(lái)
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
}
)
前臺(tái)展示文件:
!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>結(jié)果/h1>
div>
{% for item in video_list %}
p>{{ item.Video_title }}/p>
{% endfor %}
/div>
/div>
/body>
/html>
總結(jié)
以上所述是小編給大家介紹的Django 標(biāo)簽篩選的實(shí)現(xiàn)代碼(一對(duì)多、多對(duì)多),希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
您可能感興趣的文章:- Django ManyToManyField 跨越中間表查詢(xún)的方法
- django多文件上傳,form提交,多對(duì)多外鍵保存的實(shí)例
- 基于Django ORM、一對(duì)一、一對(duì)多、多對(duì)多的全面講解
- django多對(duì)多表的創(chuàng)建,級(jí)聯(lián)刪除及手動(dòng)創(chuàng)建第三張表
- django數(shù)據(jù)關(guān)系一對(duì)多、多對(duì)多模型、自關(guān)聯(lián)的建立
- Django之多對(duì)多查詢(xún)與操作方法詳解
- Django中數(shù)據(jù)庫(kù)的數(shù)據(jù)關(guān)系:一對(duì)一,一對(duì)多,多對(duì)多
- Django的數(shù)據(jù)模型訪問(wèn)多對(duì)多鍵值的方法
- django ManyToManyField多對(duì)多關(guān)系的實(shí)例詳解