码迷,mamicode.com
首页 > 编程语言 > 详细

Python CRM项目三

时间:2017-11-09 22:21:10      阅读:314      评论:0      收藏:0      [点我收藏+]

标签: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>
View Code

在项目中由于分页之前要进行条件筛选和排序,所以分页如下

技术分享
1 from django.core.paginator import Paginator,EmptyPage, PageNotAnInteger
View Code
技术分享
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
View Code
技术分享
 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})
View Code
技术分享
 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 %}
View Code

自定义标签的tags的方法

1.导入

技术分享
1 from django import template
2 from django.utils.safestring import mark_safe
3 register = template.Library()
View Code

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
View Code

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)
View Code

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 ‘‘
View Code

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)
View Code

 当然,上述的代码会导致错误,这是必然发生的,因为我们没有和之后的过滤,排序结合起来,目前只用了分页,所以比较片面,后面还需在功能上进行优化

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
View Code

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
View Code

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 ‘‘})
View Code

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)
View Code

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))
View Code

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)
View Code

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 %}
View Code

 

Python CRM项目三

标签:admin   with   tag   value   比较   condition   key   result   val   

原文地址:http://www.cnblogs.com/luhuajun/p/7800776.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!