标签:admin with tag value 比较 condition key result val
1.分页:
分页使用Django内置的分页模块来实现
官方的分页案例
1 from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger 2 from django.shortcuts import render 3 #后端 4 def listing(request): 5 contact_list = Contacts.objects.all() 6 paginator = Paginator(contact_list, 25) # Show 25 contacts per page 7 8 page = request.GET.get(‘page‘) 9 try: 10 contacts = paginator.page(page) 11 except PageNotAnInteger: 12 # If page is not an integer, deliver first page. 13 contacts = paginator.page(1) 14 except EmptyPage: 15 # If page is out of range (e.g. 9999), deliver last page of results. 16 contacts = paginator.page(paginator.num_pages) 17 18 return render(request, ‘list.html‘, {‘contacts‘: contacts}) 19 #前端 20 % for contact in contacts %} 21 {# Each "contact" is a Contact model object. #} 22 {{ contact.full_name|upper }}<br /> 23 ... 24 {% endfor %} 25 #分页组件 26 <div class="pagination"> 27 <span class="step-links"> 28 {% if contacts.has_previous %} 29 <a href="?page={{ contacts.previous_page_number }}">previous</a> 30 {% endif %} 31 32 <span class="current"> 33 Page {{ contacts.number }} of {{ contacts.paginator.num_pages }}. 34 </span> 35 36 {% if contacts.has_next %} 37 <a href="?page={{ contacts.next_page_number }}">next</a> 38 {% endif %} 39 </span> 40 </div>
在项目中由于分页之前要进行条件筛选和排序,所以分页如下
1 from django.core.paginator import Paginator,EmptyPage, PageNotAnInteger
def table_filter(request,admin_class): ‘‘‘进行条件过滤,并返回过滤后的数据和条件‘‘‘ filter_condition = {} for k,v in request.GET.items(): if v: filter_condition[k]=v return admin_class.model.objects.filter(**filter_condition),filter_condition
1 def display_table_objs(request,app_name,table_name): 2 admin_class = king_admin.enabled_admins[app_name][table_name] 3 #有后端查询出结果集和条件,并对其进行分页操作 4 object_list,filter_conditions = table_filter(request,admin_class) 5 6 paginator = Paginator(object_list, admin_class.list_per_page) 7 page = request.GET.get(‘page‘) 8 try: 9 objects = paginator.page(page) 10 except PageNotAnInteger: 11 objects = paginator.page(1) 12 except EmptyPage: 13 objects = paginator.page(paginator.num_pages) 14 15 return render(request,‘king_admin/table_objs.html‘,{‘admin_class‘:admin_class, 16 ‘query_sets‘:objects, 17 ‘filter_conditions‘:filter_conditions})
1 {% block container %} 2 <div class="panel panel-info"> 3 <div class="panel-heading"> 4 <h3 class="panel-title">Panel title</h3> 5 </div> 6 <div class="panel-body"> 7 <div class="row"> 8 {# <!--将筛选提交提交到后台进行查询--!>#} 9 <form method="get"> 10 {% for condition in admin_class.list_filters %} 11 <div class="col-lg-2"> 12 <span>{{ condition }}</span> 13 #后台通过条件,数据类,所选条件进行提取结果集 14 {% render_filter_ele condition admin_class filter_conditions %} 15 </div> 16 {% endfor %} 17 <div class="col-lg-2"> 18 <input type="submit" class="btn btn-info" style="margin-top:20px"> 19 </div> 20 </form> 21 </div> 22 {# <!--动态展示后端的表格--!>#} 23 <table class="table table-hover"> 24 <thead> 25 <tr> 26 {% for column in admin_class.list_display %} 27 <th>{{ column }}</th> 28 {% endfor %} 29 </tr> 30 </thead> 31 <tbody> 32 {# <!--动态展示后端的表格中的数据--!>#} 33 {% for obj in query_sets %} 34 <tr> 35 {% bulid_table_row obj admin_class %} 36 </tr> 37 {% endfor %} 38 </tbody> 39 </table> 40 {# <!--分页--!>#} 41 <nav aria-label="..."> 42 <ul class="pagination"> 43 {% if query_sets.has_previous %} 44 <li><a href="?page={{ query_sets.previous_page_number }}">上一页</a></li> 45 {% endif %} 46 {% for loop_counter in query_sets.paginator.page_range %} 47 {% render_page_ele loop_counter query_sets %} 48 {% endfor %} 49 {% if query_sets.has_next %} 50 <li><a href="?page={{ query_sets.next_page_number }}">下一页</a></li> 51 {% endif %} 52 </ul> 53 </nav> 54 </div> 55 </div> 56 {% endblock %}
自定义标签的tags的方法
1.导入
1 from django import template 2 from django.utils.safestring import mark_safe 3 register = template.Library()
2.动态加载表格 render_app_name
1 @register.simple_tag 2 def render_app_name(admin_class): 3 ‘‘‘渲染动态获取表名‘‘‘ 4 return admin_class.model._meta.verbose_name_plural
3.动态展示表格中的数据 build_table_row
1 @register.simple_tag 2 def bulid_table_row(obj,admin_class): 3 ‘‘‘生成数据内容的td,填充到table中,展示前端‘‘‘ 4 row_ele = ‘‘ 5 for column in admin_class.list_display: 6 #获取每个字段的类型的对象 7 field_obj = obj._meta.get_field(column) 8 #判断是否是choice字段 9 if field_obj.choices: 10 #如果是choice字段,则按照choice的值进行展示 11 column_data = getattr(obj,"get_%s_display"%column)() 12 else: 13 #否则通过反射去对象中取值 14 column_data = getattr(obj,column) 15 16 if type(column_data).__name__ == ‘datetime‘: 17 #如果是时间类型,则需要进行格式化显示 18 column_data = column_data.strftime(‘%Y-%m-%d %H:%M:%S‘) 19 row_ele += ‘<td>%s</td>‘%column_data 20 return mark_safe(row_ele)
4.动态进行分页参数的切割 render_page_ele
1 @register.simple_tag 2 def render_page_ele(loop_counter,query_sets): 3 #如果当前页数-循环的次数小于1,就展示前面两页和后面两页 4 #例如当前是第五页则展示3,4,5,6,7页 5 if abs(query_sets.number-loop_counter)<=1: 6 ele_class = ‘‘ 7 if query_sets.number==loop_counter: 8 ele_class = ‘active‘ 9 ele= ‘<li class="%s"><a href="?page=%s">%s</a></li>‘%(ele_class,loop_counter,loop_counter) 10 return mark_safe(ele) 11 return ‘‘
5.动态加载筛选条件 render_filter_ele
1 @register.simple_tag 2 def render_filter_ele(condition,admin_class,filter_conditions): 3 select_ele = ‘<select class="form-control" name="%s"><option value="">----</option>‘%condition 4 field_obj = admin_class.model._meta.get_field(condition) 5 selected = ‘‘ 6 if field_obj.choices: 7 8 #choice字段的值的获取 9 for choice_item in field_obj.choices: 10 if filter_conditions.get(condition) == str(choice_item[0]): 11 selected = ‘selected‘ 12 select_ele += ‘<option value="%s" %s>%s</option>‘%(choice_item[0],selected,choice_item[1]) 13 selected = ‘‘ 14 if type(field_obj).__name__==‘ForeignKey‘: 15 #外键字段的获取 16 for choice_item in field_obj.get_choices()[1:]: 17 if filter_conditions.get(condition) == str(choice_item[0]): 18 selected = ‘selected‘ 19 select_ele += ‘<option value="%s" %s>%s</option>‘ % (choice_item[0], selected,choice_item[1]) 20 selected = ‘‘ 21 select_ele+=‘</select>‘ 22 return mark_safe(select_ele)
当然,上述的代码会导致错误,这是必然发生的,因为我们没有和之后的过滤,排序结合起来,目前只用了分页,所以比较片面,后面还需在功能上进行优化
6.条件过滤
思路:前端传入过滤条件,后端组合成字典,同时过滤掉分页关键字和排序关键字,再将条件封装成字典,按条件查询即可
1 def table_filter(request,admin_class): 2 ‘‘‘进行条件过滤,并返回过滤后的数据‘‘‘ 3 filter_condition = {} 4 for k,v in request.GET.items(): 5 #page为分页的字段,o为排序关键字,不是数据库的查询字段,此处要进行过滤 6 if k == ‘page‘ or k == ‘o‘: 7 continue 8 if v: 9 filter_condition[k]=v 10 11 return admin_class.model.objects.filter(**filter_condition),filter_condition
7.单条件排序
思路:将前端传入的排序字段,后台拿到排序的关键字进行排序,排序分为正向排序和逆向排序
1 def table_sort(request,objs): 2 #获取前端的分页关键字进行排序 3 orderby_key = request.GET.get(‘o‘) 4 if orderby_key: 5 res = objs.order_by(orderby_key) 6 #如果上一次是降序,此时改成升序 7 if orderby_key.startswith(‘-‘): 8 orderby_key = orderby_key.strip(‘-‘) 9 else: 10 #否则改成降序 11 orderby_key = ‘-%s‘%orderby_key 12 else: 13 res = objs 14 return res,orderby_key
8.views修改,分页中集成筛选和排序
1 def display_table_objs(request,app_name,table_name): 2 admin_class = king_admin.enabled_admins[app_name][table_name] 3 #有后端查询出结果集,并对其进行分页操作 4 object_list,filter_conditions = table_filter(request,admin_class) 5 #先过滤,在排序 6 object_list,orderby_key = table_sort(request,object_list) 7 8 paginator = Paginator(object_list, admin_class.list_per_page) 9 page = request.GET.get(‘page‘) 10 try: 11 objects = paginator.page(page) 12 except PageNotAnInteger: 13 objects = paginator.page(1) 14 except EmptyPage: 15 objects = paginator.page(paginator.num_pages) 16 #传递给前端的参数有model的admin_class,分页的结果集,过滤条件,排序字段,以及上一次的排序字段 17 return render(request,‘king_admin/table_objs.html‘,{‘admin_class‘:admin_class, 18 ‘query_sets‘:objects, 19 ‘filter_conditions‘:filter_conditions, 20 ‘orderby_key‘:orderby_key, 21 ‘previous_orderby‘:request.GET.get(‘o‘) or ‘‘})
9.tags自定义标签渲染
9.1 筛选条件
1 @register.simple_tag 2 def render_filter_ele(condition,admin_class,filter_conditions): 3 #渲染过滤筛选的条件,返回给前端渲染 4 select_ele = ‘<select class="form-control" name="%s"><option value="">----</option>‘%condition 5 field_obj = admin_class.model._meta.get_field(condition) 6 selected = ‘‘ 7 if field_obj.choices: 8 9 #choice字段的值的获取 10 for choice_item in field_obj.choices: 11 if filter_conditions.get(condition) == str(choice_item[0]): 12 selected = ‘selected‘ 13 select_ele += ‘<option value="%s" %s>%s</option>‘%(choice_item[0],selected,choice_item[1]) 14 selected = ‘‘ 15 if type(field_obj).__name__==‘ForeignKey‘: 16 #外键字段的获取 17 for choice_item in field_obj.get_choices()[1:]: 18 if filter_conditions.get(condition) == str(choice_item[0]): 19 selected = ‘selected‘ 20 select_ele += ‘<option value="%s" %s>%s</option>‘ % (choice_item[0], selected,choice_item[1]) 21 selected = ‘‘ 22 select_ele+=‘</select>‘ 23 return mark_safe(select_ele)
9.2 排序关键字
1 @register.simple_tag 2 def build_table_header_column(column,orderby_key,filter_condition): 3 #排序时要携带过滤条件 4 filters = ‘‘ 5 for k,v in filter_condition.items(): 6 filters += ‘&%s=%s‘%(k,v) 7 ele = ‘<th><a href="?{filters}&o={orderby_key}">{column}</a>{sort_icon}</th>‘ 8 if orderby_key: 9 if orderby_key.startswith(‘-‘): 10 sort_icon = ‘<span class="glyphicon glyphicon-chevron-up"></span>‘ 11 else: 12 sort_icon = ‘<span class="glyphicon glyphicon-chevron-down"></span>‘ 13 14 if orderby_key.strip(‘-‘) == column: #排序的就是当前字段 15 orderby_key = orderby_key 16 17 else: 18 orderby_key = column 19 sort_icon = ‘‘ 20 21 else:#没有排序,就默认按照当前列显示 22 orderby_key = column 23 sort_icon = ‘‘ 24 return mark_safe(ele.format(orderby_key=orderby_key,column=column,sort_icon=sort_icon,filters=filters))
9.3 分页bug修复
1 @register.simple_tag 2 def build_paginations(query_sets,filter_conditions,previous_orderby): 3 ‘‘‘返回整个的分页元素‘‘‘ 4 filters = ‘‘ 5 for k, v in filter_conditions.items(): 6 filters += ‘&%s=%s‘ % (k, v) 7 8 page_btns = ‘‘ 9 added_dot_ele = False 10 for page_num in query_sets.paginator.page_range: 11 #代表最前2页,或最后2页 12 if page_num < 3 or page_num > query_sets.paginator.num_pages-2 or 13 abs(query_sets.number - page_num) <= 1: 14 ele_class = ‘‘ 15 if query_sets.number == page_num: 16 ele_class = ‘active‘ 17 added_dot_ele = False 18 page_btns += ‘<li class="%s"><a href="?page=%s%s&o=%s">%s</a></li>‘ % (ele_class, page_num, filters,previous_orderby, page_num) 19 else: 20 if not added_dot_ele:#现在还没有加... 21 page_btns += ‘<li><a>...</a></li>‘ 22 added_dot_ele = True 23 24 return mark_safe(page_btns)
10 前端页面修改
1 {% extends ‘king_admin/table_index.html‘ %} 2 {% load tags %} 3 4 {% block container %} 5 <div class="panel panel-info"> 6 <div class="panel-heading"> 7 <h3 class="panel-title">Panel title</h3> 8 </div> 9 <div class="panel-body"> 10 <div class="row"> 11 {# <!--将筛选提交提交到后台进行查询--!>#} 12 <form method="get"> 13 {% for condition in admin_class.list_filters %} 14 <div class="col-lg-2"> 15 <span>{{ condition }}</span> 16 {# 后台通过条件,数据类,所选条件进行提取结果集#} 17 {% render_filter_ele condition admin_class filter_conditions %} 18 </div> 19 {% endfor %} 20 <div class="col-lg-2"> 21 <input type="submit" class="btn btn-info" style="margin-top:20px"> 22 </div> 23 </form> 24 </div> 25 {# <!--动态展示后端的表格--!>#} 26 <table class="table table-hover"> 27 <thead> 28 <tr> 29 {% for column in admin_class.list_display %} 30 {# 动态展示表格中的数据,排序关键字,和筛选条件#} 31 {% build_table_header_column column orderby_key filter_conditions %} 32 {% endfor %} 33 </tr> 34 </thead> 35 <tbody> 36 {# <!--动态展示后端的表格中的数据--!>#} 37 {% for obj in query_sets %} 38 <tr> 39 {% bulid_table_row obj admin_class %} 40 </tr> 41 {% endfor %} 42 </tbody> 43 </table> 44 <p>总计:{{ query_sets.paginator.count }}条</p> 45 {# <!--分页--!>#} 46 <nav aria-label="..."> 47 <ul class="pagination"> 48 {% if query_sets.has_previous %} 49 <li><a href="?page={{ query_sets.previous_page_number }}">上一页</a></li> 50 {% endif %} 51 {% build_paginations query_sets filter_conditions previous_orderby %} 52 {% if query_sets.has_next %} 53 <li><a href="?page={{ query_sets.next_page_number }}">下一页</a></li> 54 {% endif %} 55 </ul> 56 </nav> 57 </div> 58 59 </div> 60 {% endblock %}
标签:admin with tag value 比较 condition key result val
原文地址:http://www.cnblogs.com/luhuajun/p/7800776.html