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="width: 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)
技术改变命运