7-crm项目-kingadmin,列表页---排序

展示客户列表页面--------排序

排序的逻辑
排序这样设计,
1,点击每一列可以倒序,再次点击可以正序,通过一个【-】,来控制的
2,点击怎么把这个关键值添加到url,点击一列排序,其他列就不排序了,--这是每次进入之后都会渲染一遍页面,没有排序的就是没有排序,下次点击就是正序排列
3,排序要加一个url的关键值就是o,
4,这是在排序的基础上做的排序-----这个要记住!!!
5,后端获取到这个关键字,怎么利用起来做排序------获取到就直接orm排序了,
6,注意分页的url也是渲染的所以要加上排序

##############

第1步:views

@login_required
def display_table_objs(request,app_name,table_name):

    print("-->",app_name,table_name)  # 这是通过url取到的,
    #models_module = importlib.import_module('%s.models'%(app_name))
    #model_obj = getattr(models_module,table_name)
    admin_class = king_admin.enabled_admins[app_name][table_name]
    #admin_class = king_admin.enabled_admins[crm][userprofile]

    if request.method == "POST": #action 来了

        print(request.POST)
        selected_ids = request.POST.get("selected_ids")
        action = request.POST.get("action")
        if selected_ids:
            selected_objs = admin_class.model.objects.filter(id__in=selected_ids.split(','))
        else:
            raise KeyError("No object selected.")
        if hasattr(admin_class,action):
            action_func = getattr(admin_class,action)
            request._admin_action = action
            return action_func(admin_class,request,selected_objs)

    #object_list = admin_class.model.objects.all()
    object_list,filter_condtions = table_filter(request,admin_class) #过滤后的结果

    object_list = table_search(request,admin_class,object_list)  # 查询后的结果

    object_list,orderby_key = table_sort(request, admin_class, object_list) #排序后的结果
    print("orderby key ", orderby_key)
    paginator = Paginator(object_list, admin_class.list_per_page)  # 分页

    page = request.GET.get('page')
    try:
        query_sets = paginator.page(page)
    except PageNotAnInteger:
        # If page is not an integer, deliver first page.
        query_sets = paginator.page(1)
    except EmptyPage:
        # If page is out of range (e.g. 9999), deliver last page of results.
        query_sets = paginator.page(paginator.num_pages)

    return render(request,"king_admin/table_objs.html",{"admin_class":admin_class,
                                                        "query_sets":query_sets,
                                                        "filter_condtions":filter_condtions,-----这是为了过滤
                                                        "orderby_key":orderby_key,-----这是为了排序的渲染url
                                                        "previous_orderby": request.GET.get("o",''),-----这是为了分页的时候加入排序渲染url
                                                        "search_text":request.GET.get('_q','')})----这是为了查询

对应的函数table_sort

def table_sort(request,admin_class,objs):------>这个方法很关键,这里获取到了排序,第一种没有排序,第二种获取到了就直接排序
    orderby_key = request.GET.get("o")
    if orderby_key:
        res = objs.order_by(orderby_key)------>这里的逻辑是为什么这样,因为你点击字段一开始是-的,下次就要去掉负的才正常,如果不是-的,就要加上,下次点击才正常
        if orderby_key.startswith("-"):
            orderby_key = orderby_key.strip("-")
        else:
            orderby_key = "-%s"%orderby_key
    else:
        res = objs
    return res,orderby_key-----orderby_key是为了下一次点击的

 注意:获取过滤条件的时候要排序这个o的关键字

def table_filter(request,admin_class):
    '''进行条件过滤并返回过滤后的数据'''
    filter_conditions = {}
    keywords = ['page','o','_q']
    for k,v in request.GET.items():
        if k in keywords:#保留的分页关键字 and 排序关键字
            continue
        if v:
            filter_conditions[k] =v
    print("filter coditions",filter_conditions)

    return admin_class.model.objects.filter(**filter_conditions).
               order_by("-%s" % admin_class.ordering if admin_class.ordering else  "-id"),
               filter_conditions

第2步:tag

@register.simple_tag
def  build_table_header_column(column,orderby_key,filter_condtions,admin_class): -----这4个参数,都是views传给前端的,
    filters = ''
    for k,v in filter_condtions.items():
        filters += "&%s=%s" %(k,v) ---->这是把过滤条件加进来,拼接成为url,

    ele = '''<th><a href="?{filters}&o={orderby_key}">{column}</a>
    {sort_icon}
    </th>'''
    if orderby_key:  ---->这是在处理排序标识的问题,倒序,正序,不排序
        if orderby_key.startswith("-"):
            sort_icon = '''<span class="glyphicon glyphicon-chevron-up"></span>'''
        else:
            sort_icon = '''<span class="glyphicon glyphicon-chevron-down"></span>'''

        if orderby_key.strip("-") == column: #排序的就是这个字段
            orderby_key =orderby_key
        else:
            orderby_key = column
            sort_icon = ''

    else:  #没有排序
        orderby_key = column-----这一句很重要就是如果没有排序,就把这个渲染成为这个字段,
        sort_icon = ''
    try:
        column_verbose_name = admin_class.model._meta.get_field(column).verbose_name.upper()  --->这是处理显示到页面,字段展示什么
    except FieldDoesNotExist  as e:
        column_verbose_name = getattr(admin_class,column).display_name.upper()
        ele = '''<th><a href="javascript:void(0);">{column}</a></th>'''.format(column=column_verbose_name)
        return mark_safe(ele)

    ele = ele.format(orderby_key=orderby_key, column=column_verbose_name,sort_icon=sort_icon,filters=filters)
    return mark_safe(ele )

第3步:html

<thead>
                    <tr>
                        <th style=" 35px"><input type="checkbox" onclick="CheckAllToggle(this)" ></th>
                        {% for column in admin_class.list_display %}
                            {% build_table_header_column column orderby_key filter_condtions admin_class%}

                        {% endfor %}
                    </tr>
                  </thead>

注意分页要加上排序:

@register.simple_tag
def build_paginators(query_sets,filter_condtions,previous_orderby,search_text):
    '''返回整个分页元素'''
    page_btns = ''
    filters = ''
    for k,v in filter_condtions.items():
        filters += "&%s=%s" %(k,v)


    added_dot_ele = False #
    for page_num in query_sets.paginator.page_range:
        if page_num < 3 or page_num > query_sets.paginator.num_pages -2 
                or abs(query_sets.number - page_num) <= 2: #代表最前2页或最后2页 #abs判断前后1页
            ele_class = ""
            if query_sets.number == page_num:
                added_dot_ele = False
                ele_class = "active"
            page_btns += '''<li class="%s"><a href="?page=%s%s&o=%s&_q=%s">%s</a></li>''' % (
            ele_class, page_num, filters,previous_orderby, search_text,page_num)
        # elif abs(query_sets.number - page_num) <= 1: #判断前后1页
        #     ele_class = ""
        #     if query_sets.number == page_num:
        #         added_dot_ele = False
        #         ele_class = "active"
        #     page_btns += '''<li class="%s"><a href="?page=%s%s">%s</a></li>''' % (
        #     ele_class, page_num, filters, page_num)
        else: #显示...
            if added_dot_ele == False: #现在还没加...
                page_btns += '<li><a>...</a></li>'
                added_dot_ele = True


    return mark_safe(page_btns)
原文地址:https://www.cnblogs.com/andy0816/p/13471520.html