zoukankan      html  css  js  c++  java
  • Python CRM项目三

    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

     11 排序

    后台处理

     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         if orderby_key.startswith('-'):
     7             orderby_key = orderby_key.strip('-')
     8         else:
     9             orderby_key = '-%s'%orderby_key
    10     else:
    11         res = objs
    12     return res,orderby_key
    View Code

    tags动态生成标签和触发正序和倒序

     1 @register.simple_tag
     2 def build_table_header_column(column,orderby_key,filter_condition):
     3     filters = ''
     4     for k,v in filter_condition.items():
     5         filters += '&%s=%s'%(k,v)
     6     #生成每一列表头的超链接,点击触发排序
     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

    12 查找

    后台处理

    1 def table_search(request,admin_class,object_list):
    2     search_key = request.GET.get('_q','')
    3     con = Q()
    4     con.connector = 'OR'
    5     for search_field in admin_class.search_fields:
    6         con.children.append(('%s__contains'%search_field,search_key))
    7     res = object_list.filter(con)
    8     return res
    View Code

    原先代码修改

     1 def table_filter(request,admin_class):
     2     '''进行条件过滤,并返回过滤后的数据'''
     3     filter_condition = {}
     4     # page为分页的字段,o为排序关键字,_q是搜索关键字,不是数据库的查询字段,此处要进行过滤
     5     keywords = ['page','o','_q']
     6     for k,v in request.GET.items():
     7 
     8         if k in keywords:
     9             continue
    10         if v:
    11             filter_condition[k]=v
    12 
    13     return admin_class.model.objects.filter(**filter_condition),filter_condition
    View Code

    在views中导入utils的查找方法

     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 = table_search(request,admin_class,object_list)
     7     #先过滤,在排序
     8     object_list,orderby_key = table_sort(request,object_list)
     9 
    10     paginator = Paginator(object_list, admin_class.list_per_page)
    11     page = request.GET.get('page')
    12     try:
    13         objects = paginator.page(page)
    14     except PageNotAnInteger:
    15         objects = paginator.page(1)
    16     except EmptyPage:
    17         objects = paginator.page(paginator.num_pages)
    18 
    19     return render(request,'king_admin/table_objs.html',{'admin_class':admin_class,
    20                                                        'query_sets':objects,
    21                                                         'filter_conditions':filter_conditions,
    22                                                         'orderby_key':orderby_key,
    23                                                         'previous_orderby':request.GET.get('o') or '',
    24                                                         'search_text':request.GET.get('_q') or ''})
    View Code

    前端

    1 <div class="row">
    2                         <div class="col-lg-2">
    3                             <input type="search" name="_q" style="margin-left:15px" class="form-control" value="{{ search_text }}">
    4                         </div>
    5                         <div class="col-lg-2">
    6                             <button type="submit" class="btn btn-info">搜索</button>
    7                         </div>
    8                     </div>
    View Code

    13 时间检索

     1 @register.simple_tag
     2 def render_filter_ele(condition,admin_class,filter_conditions):
     3     select_ele = '<select class="form-control" name="{condition}"><option value="">----</option>'
     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     if type(field_obj).__name__ in ['DateTimeField','DateField']:
    22         #日期字段获取,通过计算当前时间-天数来实现日期过滤
    23         date_els = []
    24         today_ele = datetime.now().date()
    25         date_els.append(['今天',today_ele])
    26         date_els.append(['昨天',today_ele - timedelta(days=1)])
    27         date_els.append(['近7天', today_ele - timedelta(days=7)])
    28         date_els.append(['本月', today_ele.replace(day=1)])
    29         date_els.append(['近30天', today_ele - timedelta(days=30)])
    30         date_els.append(['近90天', today_ele - timedelta(days=90)])
    31         date_els.append(['近180天', today_ele - timedelta(days=180)])
    32         date_els.append(['本年', today_ele.replace(month=1,day=1)])
    33         date_els.append(['近一年', today_ele - timedelta(days=365)])
    34         selected = ''
    35         for date in date_els:
    36             select_ele += '<option value="%s" %s>%s</option>'%(date[1],selected,date[0])
    37         filter_field_name = '%s__gte'%condition
    38     else:
    39         filter_field_name = condition
    40 
    41     select_ele+='</select>'
    42     select_ele=select_ele.format(condition=filter_field_name)
    43     return mark_safe(select_ele)
    View Code
  • 相关阅读:
    环境变量
    查看进程的环境变量
    shell打印彩色输出
    python使用smtplib发送邮件
    多线程实现ping扫描
    python ssh之paramiko模块使用
    Windows环境安装tesseract-ocr 4.00并配置环境变量
    Scrapy教程,亲测能用
    pycharm 调试 scrapy
    Python中元组,列表,字典的区别
  • 原文地址:https://www.cnblogs.com/luhuajun/p/7800776.html
Copyright © 2011-2022 走看看