转自:https://www.jianshu.com/p/a86281df530e

 

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。

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 %}引入模板标签。

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 # 小米6、小米8、红米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.html

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)
扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄