Django多條件篩選查詢

轉自:https://www.jianshu.com/p/a86281df530ehtml

 

Django多條件篩選查詢

主模型只存在外鍵一對多關係

模型設計

# 快捷篩選狀態 class Status(models.Model): order_number = models.PositiveIntegerField(unique=True, verbose_name='狀態編號') status_tag = models.CharField(max_length=10, verbose_name='狀態名稱') class Meta: ordering = ['order_number', ] verbose_name = '事件選擇' verbose_name_plural = verbose_name def __str__(self): return self.status_tag # 項目分類 class Project(models.Model): project_name = models.CharField(max_length=10, verbose_name='項目名稱') class Meta: ordering = ['project_name'] verbose_name = '項目分類' verbose_name_plural = verbose_name def __str__(self): return self.project_name # 事件分類 class Category(models.Model): category_name = models.CharField(max_length=10, verbose_name='分類名稱') class Meta: ordering = ['category_name', ] verbose_name = '事件分類' verbose_name_plural = verbose_name def __str__(self): return self.category_name # 事件級別 class Level(models.Model): order_number = models.PositiveIntegerField(unique=True, verbose_name='級別編號') level_tag = models.CharField(max_length=10, verbose_name='級別名稱') class Meta: ordering = ['order_number', ] verbose_name = '事件級別' verbose_name_plural = verbose_name def __str__(self): return self.level_tag # 事件內容 class EventContent(models.Model): title = models.CharField(max_length=50, verbose_name='事件標題') content = models.TextField(verbose_name='事件正文') image = models.ImageField(upload_to='images/%Y/%m', blank=True, null=True, verbose_name='描述圖片') created = models.DateTimeField(auto_now_add=True, verbose_name='建立時間') updated = models.DateTimeField(auto_now=True, verbose_name='更新時間') status = models.ForeignKey(Status, on_delete=models.SET_NULL, null=True, blank=True, related_name='event_content', verbose_name='事件狀態') project = models.ForeignKey(Project, on_delete=models.SET_NULL, null=True, blank=True, related_name='event_content', verbose_name='項目分類') category = models.ForeignKey(Category, on_delete=models.CASCADE, related_name='event_content', verbose_name='事件分類') level = models.ForeignKey(Level, on_delete=models.SET_NULL, null=True, blank=True, related_name='event_content', verbose_name='事件級別') user = models.ForeignKey(User, related_name='event_content', verbose_name='建立人') start_time = models.DateTimeField(default=timezone.now, verbose_name='事件開始時間') end_time = models.DateTimeField(default=timezone.now, verbose_name='事件結束時間') pause_time = models.DateTimeField(default=timezone.now, verbose_name='事件暫停時間') class Meta: ordering = ['-created'] verbose_name = '事件內容' verbose_name_plural = verbose_name def time_interval(self): time_diff = (self.end_time-timezone.now()) days = time_diff.days seconds = time_diff.seconds minutes = seconds // 60 # 獲得這些秒換算的分鐘整數 second = seconds % 60 # 獲得除去分鐘後剩餘的秒數 hours = minutes // 60 minute = minutes % 60 if self.status.order_number == 6: return '事件已關閉!' if days <= -1: return '處理已超時!' return '{}天{}時{}分'.format(days, hours, minute) def __str__(self): return self.title def get_content_as_markdown(self): """ 當使用Mardown功能時,咱們須要先讓它轉義一下特殊字符,而後再解析出Markdown標籤。 這樣作以後,輸出字符串能夠安全的在模板中使用。 :return: """ return mark_safe(markdown(self.content, safe_mode='escape')) 

路由設計

url(r'^event/$', event, name='event'), url(r'^event-(?P<user_id>\d+)-(?P<status_id>\d+)-(?P<level_id>\d+)-(?P<category_id>\d+)-(?P<project_id>\d+).html$', event, name='event_filter'), 

視圖設計

該視圖只須要查看kwargs有值的狀況前端

def get_group_url_list(url): """ 將訪問的url存儲在列表中,用於前端判斷 EVENT_MENU_GROUP : 事件菜單組 OTHER_MENU_GROUP : 其餘菜單組 :param url: :return: """ group_url_list = list() group_url_list.append(url) return group_url_list # 顯示事件列表 def event(request, **kwargs): print('視圖**kwargs的值:', kwargs) if not kwargs: # 原來的事件列表和post篩選 # events = EventContent.objects.all() queryset = EventContent.objects.all() if request.method == 'POST': visit_url = reverse('event') event_url_list = get_group_url_list(visit_url) filter_event_form = FilterEventForm(request.POST) if filter_event_form.is_valid(): print('表單驗證經過') user = filter_event_form.cleaned_data['user'] status = filter_event_form.cleaned_data['status'] project = filter_event_form.cleaned_data['project'] category = filter_event_form.cleaned_data['category'] level = filter_event_form.cleaned_data['level'] queryset = queryset.filter(user=user, status=status, project=project, category=category, level=level) print(queryset) else: visit_url = reverse('event') event_url_list = get_group_url_list(visit_url) filter_event_form = FilterEventForm() page = request.GET.get('page', 1) paginator = Paginator(queryset, settings.PAGE_NUM) # paginator是分頁對象 try: events = paginator.page(page) except PageNotAnInteger: events = paginator.page(1) except EmptyPage: events = paginator.page(paginator.num_pages) return render(request, 'event.html', { 'events': events, 'EVENT_MENU_GROUP': event_url_list, 'filter_event_form': filter_event_form, 'old_filter': True }) else: """ 多條件事件篩選 event-(?P<user_id>\d+)-(?P<status_id>\d+)-(?P<level_id>\d+)-(?P<category_id>\d+)-(?P<project_id>\d+).html {'user_id': '0', 'status_id': '0', 'level_id': '0', 'category_id': '0', 'project_id': '0'} """ filter_dict = dict() request_path = request.path print('請求地址:', request_path) if kwargs['user_id'] != '0': filter_dict['user'] = get_object_or_404(User, id=kwargs['user_id']) if kwargs['status_id'] != '0': filter_dict['status'] = get_object_or_404(Status, id=kwargs['status_id']) if kwargs['level_id'] != '0': filter_dict['level'] = get_object_or_404(Level, id=kwargs['level_id']) if kwargs['category_id'] != '0': filter_dict['category'] = get_object_or_404(Category, id=kwargs['category_id']) if kwargs['project_id'] != '0': filter_dict['project'] = get_object_or_404(Project, id=kwargs['project_id']) user_list = User.objects.all().values('id', 'username') # print(user_list) status_list = Status.objects.all().values('id', 'status_tag') # print(status_list) level_list = Level.objects.all().values('id', 'level_tag') category_list = Category.objects.all().values('id', 'category_name') project_list = Project.objects.all().values('id', 'project_name') url_id_list = kwargs.values() # url中全部id:[0, 0, 0, 0, 0 ] visit_url = reverse('event_filter', args=url_id_list) event_url_list = get_group_url_list(visit_url) queryset = EventContent.objects.filter(**filter_dict) page = request.GET.get('page', 1) paginator = Paginator(queryset, settings.PAGE_NUM) # paginator是分頁對象 try: events = paginator.page(page) except PageNotAnInteger: events = paginator.page(1) except EmptyPage: events = paginator.page(paginator.num_pages) return render(request, 'event.html', { 'events': events, 'EVENT_MENU_GROUP': event_url_list, 'user_list': user_list, 'status_list': status_list, 'level_list': level_list, 'category_list': category_list, 'project_list': project_list, }) 

模板設計

<div class="card-header"> <h3 class="card-title">事件列表</h3> </div> <!-- /.card-header --> {% if old_filter %} <div class="card-body card-comment"> <form role="form" action="{% url 'event' %}?page=2" method="post"> <div class="row"> <div class="col-2"> <div class="input-group mb-12"> {% with filter_event_form.user as filter_fields %} <div class="input-group-prepend"> <label class="input-group-text {% if filter_fields.errors %}bg-danger {% endif %}" for="{{ filter_fields.id_for_label }}">{{ filter_fields.label }}</label> </div> <select class="form-control col-sm-12" name="user" id="{{ filter_fields.id_for_label }}"> <option>{% for select in filter_fields %}{{ select }}{% endfor %}</option> </select> {% endwith %} </div> </div> <div class="col-2"> <div class="input-group mb-12"> {% with filter_event_form.status as filter_fields %} <div class="input-group-prepend"> <label class="input-group-text {% if filter_fields.errors %}bg-danger{% endif %}" for="{{ filter_fields.id_for_label }}">{{ filter_fields.label }}</label> </div> <select class="form-control col-sm-12" name="status" id="{{ filter_fields.id_for_label }}"> <option>{% for select in filter_fields %}{{ select }}{% endfor %}</option> </select> {% endwith %} </div> </div> <div class="col-2"> <div class="input-group mb-12"> {% with filter_event_form.project as filter_fields %} <div class="input-group-prepend"> <label class="input-group-text {% if filter_fields.errors %}bg-danger {% endif %}" for="{{ filter_fields.id_for_label }}">{{ filter_fields.label }}</label> </div> <select class="form-control col-sm-12" name="project" id="{{ filter_fields.id_for_label }}"> <option>{% for select in filter_fields %}{{ select }}{% endfor %}</option> </select> {% endwith %} </div> </div> <div class="col-2"> <div class="input-group mb-12"> {% with filter_event_form.category as filter_fields %} <div class="input-group-prepend"> <label class="input-group-text {% if filter_fields.errors %}bg-danger {% endif %}" for="{{ filter_fields.id_for_label }}">{{ filter_fields.label }}</label> </div> <select class="form-control col-sm-12" name="category" id="{{ filter_fields.id_for_label }}"> <option>{% for select in filter_fields %}{{ select }}{% endfor %}</option> </select> {% endwith %} </div> </div> <div class="col-2"> <div class="input-group mb-12"> {% with filter_event_form.level as filter_fields %} <div class="input-group-prepend"> <label class="input-group-text {% if filter_fields.errors %}bg-danger {% endif %}" for="{{ filter_fields.id_for_label }}">{{ filter_fields.label }}</label> </div> <select class="form-control col-sm-12" name="level" id="{{ filter_fields.id_for_label }}"> <option>{% for select in filter_fields %}{{ select }}{% endfor %}</option> </select> {% endwith %} </div> </div> <button type="submit" class="btn btn-primary">篩選事件</button> </div> {% csrf_token %} </form> </div> {% else %} <div class="card-body d-flex p-0"> <h3 class="card-title p-3">用戶</h3> <ul class="nav nav-pills p-2"> {% active_all request.path 1 %} {% for user_item in user_list %} {% active request.path user_item 1 %} {% endfor %} </ul> </div> <div class="card-body d-flex p-0"> <h3 class="card-title p-3">狀態</h3> <ul class="nav nav-pills p-2"> {% active_all request.path 2 %} {% for status_item in status_list %} {% active request.path status_item 2 %} {% endfor %} </ul> </div> <div class="card-body d-flex p-0"> <h3 class="card-title p-3">級別</h3> <ul class="nav nav-pills p-2"> {% active_all request.path 3 %} {% for level_item in level_list %} {% active request.path level_item 3 %} {% endfor %} </ul> </div> <div class="card-body d-flex p-0"> <h3 class="card-title p-3">分類</h3> <ul class="nav nav-pills p-2"> {% active_all request.path 4 %} {% for category_item in category_list %} {% active request.path category_item 4 %} {% endfor %} </ul> </div> <div class="card-body d-flex p-0"> <h3 class="card-title p-3">項目</h3> <ul class="nav nav-pills p-2"> {% active_all request.path 5 %} {% for project_item in project_list %} {% active request.path project_item 5 %} {% endfor %} </ul> </div> {% endif %} 

連接生成模板標籤

使用模板標籤,在應用下建立templatetags的python包,而後建立active.py文件,須要在模板中經過{% load active %}引入模板標籤。python

from django.utils.safestring import mark_safe from django import template register = template.Library() @register.simple_tag def active_all(request_path, index): url_part_list = request_path.split('-') # print(url_part_list) # ['/event', '0', '0', '0', '0', '0.html'] # 第五組帶.html,須要分開判斷 if url_part_list[index] == '0' or url_part_list[index] == '0.html': temp = ''' <li class="nav-item"> <a class="nav-link active" href="{href}">所有</a> </li> ''' else: temp = ''' <li class="nav-item"> <a class="nav-link" href="{href}">所有</a> </li> ''' if index != 5: url_part_list[index] = '0' else: url_part_list[index] = '0.html' href = '-'.join(url_part_list) return mark_safe(temp.format(href=href)) @register.simple_tag def active(request_path, item, index): url_part_list = request_path.split('-') # 下面判斷中,前面表示 event-0-1-5-1-,後面表示 3.html if url_part_list[index] == str(item['id']) or url_part_list[index] == str(item['id']) + '.html': temp = ''' <li class="nav-item"> <a href="{href}" class="nav-link active">{name}</a> </li> ''' else: temp = ''' <li class="nav-item"> <a href="{href}" class="nav-link">{name}</a> </li> ''' if index == 5: # 第五組有後綴.html,需單獨處理 url_part_list[index] = str(item['id']) + '.html' else: url_part_list[index] = str(item['id']) href = '-'.join(url_part_list) if index == 1: """ event-1-0-0-0-0.html event-2-0-0-0-0.html event-3-0-0-0-0.html """ return mark_safe(temp.format(href=href, name=item['username'])) if index == 2: return mark_safe(temp.format(href=href, name=item['status_tag'])) if index == 3: return mark_safe(temp.format(href=href, name=item['level_tag'])) if index == 4: return mark_safe(temp.format(href=href, name=item['category_name'])) if index == 5: return mark_safe(temp.format(href=href, name=item['project_name'])) 

兩級分類篩選

模型設計

from django.db import models from django.utils.timezone import now class GoodsTag(models.Model): name = models.CharField(max_length=64, verbose_name='標籤名稱') def __str__(self): return self.name class Meta: ordering = ['name', ] verbose_name = '商品標籤' # 後臺顯示模型名稱 verbose_name_plural = verbose_name # 智能家居、手機、電視、電腦 class FirstCategory(models.Model): name = models.CharField(max_length=64, verbose_name='分類名稱') def __str__(self): return self.name class Meta: ordering = ['name', ] verbose_name = '一級分類' verbose_name_plural = verbose_name # 小米六、小米八、紅米10 class SubCategory(models.Model): name = models.CharField(max_length=64, verbose_name='分類名稱') first_category = models.ForeignKey(FirstCategory, related_name='sub_categories', verbose_name='上級分類') def __str__(self): return self.name class Meta: ordering = ['name', ] verbose_name = '二級分類' verbose_name_plural = verbose_name class GoodsInfo(models.Model): STATUS_CHOICES = ( (1, '上架'), (2, '下架'), ) title = models.CharField(max_length=100, verbose_name='標題') content = models.TextField(blank=True, null=True, verbose_name='正文') image = models.FileField(upload_to='images/goods/%Y/%m', blank=True, null=True, verbose_name='圖片') status = models.IntegerField(choices=STATUS_CHOICES, default=1, verbose_name='狀態') created_time = models.DateTimeField(auto_now_add=True, verbose_name='建立時間') publish_time = models.DateTimeField(blank=True, null=True, default=now, verbose_name='發佈時間') updated_time = models.DateTimeField(auto_now=True, verbose_name='更新時間') category = models.ForeignKey(SubCategory, on_delete=models.CASCADE, related_name='goods_info', verbose_name='所屬分類') tags = models.ManyToManyField(GoodsTag, blank=True, verbose_name='標籤集合') def __str__(self): return self.title class Meta: verbose_name = '商品信息' verbose_name_plural = verbose_name 

主路由

urlpatterns = [ url(r'^test/', include('multiple_filter.urls', namespace='test')), ] 

應用路由

訪問 http://127.0.0.1:8000/test/goods.html 可跳轉到 http://127.0.0.1:8000/test/goods-0-0-0-0.htmldjango

urlpatterns = [ url(r'^goods.html$', goods, name='goods'), url(r'^goods-(?P<first_category_id>\d+)-(?P<sub_category_id>\d+)-(?P<tags_id>\d+)-(?P<status_id>\d+).html', goods, name='goods_filter'), ] 

視圖

from .models import GoodsTag, FirstCategory, SubCategory, GoodsInfo from django.shortcuts import get_object_or_404 def goods(request, **kwargs): if not kwargs: return redirect('test:goods_filter', first_category_id='0', sub_category_id='0', tags_id='0', status_id='0') else: request_path = request.path print('\n當前請求路徑:', request_path, '\n') print('kwargs:', kwargs) # {'first_category_id': '0', 'sub_category_id': '0', 'tags_id': '0', 'status_id': '0'} goods_tag_list = GoodsTag.objects.all().values('id', 'name') first_category_list = FirstCategory.objects.all().values('id', 'name') sub_category_list = SubCategory.objects.all().values('id', 'name') status_list = list(map(lambda x: {'id': x[0], 'status': x[1]}, GoodsInfo.STATUS_CHOICES)) filter_dict = dict() if kwargs['first_category_id'] == '0': # goods-0-x-x-x.html if kwargs['sub_category_id'] != '0': # goods-0-1-x-x.html sub_category = get_object_or_404(SubCategory, id=kwargs['sub_category_id']) # 選擇二級分類後,因爲多對一關係,一級分類也會跟着變化 first_category_list = [{'id': sub_category.first_category.id, 'name': sub_category.first_category.name}] filter_dict['category'] = sub_category else: # 一級分類不爲0,須要進行篩選 # goods-1-x-x-x.html first_category = get_object_or_404(FirstCategory, id=kwargs['first_category_id']) sub_category_list = first_category.sub_categories.values('id', 'name') # 選擇一級分類後獲取二級分類的列表 if kwargs['sub_category_id'] != '0': sub_category = get_object_or_404(SubCategory, id=kwargs['sub_category_id'], first_category=first_category) # 選擇二級分類後,因爲多對一關係,一級分類也會跟着變化 first_category_list = [{'id': sub_category.first_category.id, 'name': sub_category.first_category.name}] filter_dict['category'] = sub_category if kwargs['tags_id'] != '0': filter_dict['tags'] = kwargs['tags_id'] if kwargs['status_id'] != '0': filter_dict['status'] = int(kwargs['status_id']) goods_list = GoodsInfo.objects.filter(**filter_dict) return render(request, 'goods.html', { 'first_category_list': first_category_list, 'sub_category_list': sub_category_list, 'goods_tag_list': goods_tag_list, 'status_list': status_list, 'goods_list': goods_list }) 

模板

<!DOCTYPE html> {% load goods_active %} <html lang="en"> <head> <meta charset="UTF-8"> <title>多條件篩選</title> </head> <body> {% active_all request.path 1 %} {% for first_category in first_category_list %} {% active request.path first_category 1 %} {% endfor %} <br><br> {% active_all request.path 2 %} {% for sub_category in sub_category_list %} {% active request.path sub_category 2 %} {% endfor %} <br><br> {% active_all request.path 3 %} {% for goods_tag in goods_tag_list %} {% active request.path goods_tag 3 %} {% endfor %} <br><br> {% active_all request.path 4 %} {% for status in status_list %} {% active request.path status 4 %} {% endfor %} <p> {% for goods in goods_list %} <p> 【{{ goods.title }}】{{ goods.content }} </p> {% endfor %} </p> </body> </html> 

連接生成模板標籤

應用下建立templatetags包,建立 goods_active.py 文件,用來放置模板標籤編程

from django.utils.safestring import mark_safe from django import template register = template.Library() @register.simple_tag def active_all(current_url, index): """ 獲取當前url,進行值修改拼接 :param current_url: http://127.0.0.1:8000/test/goods-0-0-0-0.html :param index: :return: """ a_href_active = """ <a href="{href}" class="active">【所有】</a> """ a_href_unactive = """ <a href="{href}">所有</a> """ url_part_list = current_url.split('-') if index == len(url_part_list)-1: # 最後一個帶.html要特殊處理 if url_part_list[index] == '0.html': a_href = a_href_active else: a_href = a_href_unactive url_part_list[index] = '0.html' else: if url_part_list[index] == '0': a_href = a_href_active else: a_href = a_href_unactive url_part_list[index] = '0' href = '-'.join(url_part_list) a_href = a_href.format(href=href) return mark_safe(a_href) @register.simple_tag def active(current_url, item, index): """ 獲取當前url,進行值修改拼接 :param current_url: http://127.0.0.1:8000/test/goods-0-0-0-0.html :param index: :return: """ a_href_active = """ <a href="{href}" class="active">【{name}】</a> """ a_href_unactive = """ <a href="{href}">{name}</a> """ url_part_list = current_url.split('-') if index == len(url_part_list)-1: # 最後一個帶.html要特殊處理 if url_part_list[index] == str(item['id']) + '.html': a_href = a_href_active else: a_href = a_href_unactive url_part_list[index] = str(item['id']) + '.html' else: # print(item['id'], type(item['id'])) # item['id']是int類型 if url_part_list[index] == str(item['id']): a_href = a_href_active else: a_href = a_href_unactive url_part_list[index] = str(item['id']) href = '-'.join(url_part_list) if index in range(1, 4): a_href = a_href.format(href=href, name=item['name']) if index == len(url_part_list)-1: a_href = a_href.format(href=href, name=item['status']) return mark_safe(a_href) 

多對多模型進行篩選

模型

# 課程分類 class Category(models.Model): weight = models.IntegerField(verbose_name='權重(按從大到小排列)', default=0) name = models.CharField(max_length=32, verbose_name='分類名稱') class Meta: verbose_name = '分類方向' verbose_name_plural = verbose_name def __str__(self): return self.name # 編程語言,一個課程分類裏可能有多種編程語言,一種編程語言可能存在不一樣的課程分類 class Code(models.Model): weight = models.IntegerField(default=0, verbose_name='權重(按從大到小排列)') name = models.CharField(max_length=32, verbose_name='編程語言') category = models.ManyToManyField(Category, related_name='codes', verbose_name='課程分類') class Meta: verbose_name = '編程語言' verbose_name_plural = verbose_name def __str__(self): return self.name # 課程詳情 class Course(models.Model): STATUS_CHOICE = ( (0, '下線'), (1, '上線') ) LEVEL_CHOICE = ( (1, '初級'), (2, '中級'), (3, '高級') ) status = models.IntegerField(choices=STATUS_CHOICE, default=1, verbose_name='狀態') level = models.IntegerField(choices=LEVEL_CHOICE, default=1, verbose_name='難度級別') category = models.ForeignKey(Category, null=True, blank=True, related_name='courses', verbose_name='課程分類') weight = models.IntegerField(default=0, verbose_name='權重(按從大到小排列)') title = models.CharField(max_length=32, verbose_name='標題') summary = models.CharField(max_length=100, verbose_name='簡介') image = models.ImageField(upload_to='images/course/%Y/%m', verbose_name='圖片') video_url = models.CharField(max_length=256, verbose_name='視頻地址') create_time = models.DateTimeField(auto_now_add=True, verbose_name='建立時間') class Meta: verbose_name = '課程詳情' verbose_name_plural = verbose_name def __str__(self): return self.title 

路由

urlpatterns = [ # 訪問形式http://127.0.0.1:8000/test/course-0-0-0.html, # 第一個0表明課程分類,第二個0表明編程語言,第三個0表明課程級別 # 0表明所有,而後遞增,當選擇課程分類中的第一項,第一個0就會變成1 url(r'^course-(?P<code_id>\d+)-(?P<category_id>\d+)-(?P<level_id>\d+).html', course, name='course'), ] 

視圖

def course(request, *args, **kwargs): print(args, kwargs) # () {'code_id': '0', 'category_id': '0', 'level_id': '0'} request_path = request.path # http://127.0.0.1:8000/test/course-0-0-0.html # 篩選字典 filter_dict = dict() code_list = Code.objects.all().values('id', 'name') category_list = Category.objects.all().values('id', 'name') level_list = list(map(lambda x: {'id': x[0], 'name': x[1]}, Course.LEVEL_CHOICE)) if kwargs['code_id'] == '0': if kwargs['category_id'] != '0': category_list = Category.objects.filter(id=kwargs['category_id']).values('id', 'name') category = get_object_or_404(Category, id=kwargs['category_id']) # 分類不是所有,獲得這個分類對應的全部編程語言 code_list = category.codes.values('id', 'name') # 篩選這一分類 filter_dict['category'] = category else: # 若是編程語言不爲0,則獲取對應的編程語言 code = get_object_or_404(Code, id=kwargs['code_id']) # 獲得編程語言對應的全部分類 categories = code.category.all() category_list = categories.values('id', 'name') # 篩選課程在這些分類的結果 filter_dict['category__in'] = categories if kwargs['category_id'] != '0': # 若是分類不爲0,對分類進行篩選,獲得該編程語言和該分類下的結果 category = get_object_or_404(categories, id=kwargs['category_id']) code_list = category.codes.values('id', 'name') filter_dict['category'] = category if kwargs['level_id'] != '0': filter_dict['level'] = int(kwargs['level_id']) filter_dict['status'] = 1 course_list = Course.objects.filter(**filter_dict) return render(request, 'course.html', { 'category_list': category_list, 'code_list': code_list, 'level_list': level_list, 'course_list': course_list, }) 

模板

<!DOCTYPE html> {% load course_active %} <html lang="en"> <head> <meta charset="UTF-8"> <title>多條件篩選多對多模型</title> </head> <body> <h3>選擇:</h3> <p> 編程語言: {% active_all request.path 1 %} {% for code in code_list %} <!--{{ code }}--> {% active request.path code 1 %} {% endfor %} </p> <p> 課程分類: {% active_all request.path 2 %} {% for category in category_list %} <!--{{ category }}--> {% active request.path category 2 %} {% endfor %} </p> <p> 課程信息: {% active_all request.path 3 %} {% for level in level_list %} <!--{{ level }}--> {% active request.path level 3 %} {% endfor %} </p> <h3>視頻:</h3> {% for course in course_list %} <a class="item" href="{{ course.video.url }}"> <img src="/media/{{ course.image }}" width="300px" height="200px"> <p>《{{ course.title }}》{{ course.summary }}</p> <hr> </a> {% endfor %} </body> </html> 

連接生成模板標籤

應用下建立templatetags包,建立 course_active.py 文件,用來放置模板標籤安全

from django.utils.safestring import mark_safe from django import template register = template.Library() @register.simple_tag def active_all(current_url, index): """ 獲取當前url, course-1-1-2.html :param current_url: :param index: :return: """ url_part_list = current_url.split('-') if index == 3: if url_part_list[index] == '0.html': temp = '<a href="%s" class="active">【所有】</a>' else: temp = '<a href="%s"">所有</a>' url_part_list[index] = '0.html' else: if url_part_list[index] == '0': temp = '<a href="%s" class="active">【所有】</a>' else: temp = '<a href="%s"">所有</a>' url_part_list[index] = '0' url_str = '-'.join(url_part_list) temp = temp % (url_str, ) return mark_safe(temp) @register.simple_tag def active(current_url, item, index): """ course-0-0-1.html :param current_url: :param item: :param index: :return: """ # print('\n當前訪問地址:', current_url, item, index, type(index)) url_part_list = current_url.split('-') # print(url_part_list) # ['/test/course', '0', '0', '0.html'] if index == 3: if str(item['id']) == url_part_list[3].split('.')[0]: # 若是當前標籤被選中 temp = '<a href="%s" class="active">【%s】</a>' else: temp = '<a href="%s"">%s</a>' url_part_list[index] = str(item['id']) + '.html' # 拼接對應位置的url else: if str(item['id']) == url_part_list[index]: temp = '<a href="%s" class="active">【%s】</a>' else: temp = '<a href="%s">%s</a>' url_part_list[index] = str(item['id']) url_str = '-'.join(url_part_list) # 拼接總體url # print(url_str) temp = temp % (url_str, item['name']) # 生成對應的a標籤 return mark_safe(temp)
相關文章
相關標籤/搜索