11-crm项目-kingadmin,列表页actions功能开发

如果实现action的功能:

前端:

1,前端要加一个入口,可以选择某一个action,并且执行,

2,前端需要给每一个数据都增加一个复选框,增加js能选中批量操作的数据,

注意只是选择本页的,不是全部的,

怎么把选中的数据传到后台处理呢???

后端:

3,执行之后后端需要有处理函数

4,要做成可配置的,在基类里面做一个配置入口,

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

在所有数据前面加一个复选框,

              <table class="table table-hover">
                  <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>
                  <tfoot>
                    <tr>
                        <td></td>
                        <td>总计{{ query_sets.paginator.count }}条</td></tr>
                  </tfoot>
                  <tbody>
{#                    {% get_query_sets  admin_class as query_sets %}#}
                    {% for obj in query_sets %}
                    <tr>
                        <td ><input tag="obj_checkbox" type="checkbox" value="{{ obj.id }}"></td>
                        {% build_table_row request obj admin_class %}
                    </tr>
                    {% endfor %}
                  </tbody>

              </table>

增加action的操作入口:

                <div class="row" style="margin-top: 10px">  
                    <form onsubmit="return ActionSubmit(this)" method="POST">{% csrf_token %}    
               ---把这个action放到了表单里面,post方式,this就是这个表单,
<div class="col-lg-2"> <select id="action_list" name="action" class="form-control" style="margin-left:15px"> <option value="">---------</option> {% for action in admin_class.actions %} <option value="{{ action }}">{% get_action_verbose_name admin_class action %}</option> {% endfor %} </select> </div> <div class="col-lg-1" > <button type="submit" class="btn " >Go</button> </div> </form>   </div>

对应的tag

@register.simple_tag
def get_action_verbose_name(admin_class,action):

    action_func = getattr(admin_class,action)
    return  action_func.display_name if hasattr(action_func,'display_name') else action

对应的js

    <script>
        function CheckAllToggle(ele){
            if ( $(ele).prop("checked")){
                $("input[tag='obj_checkbox']").prop("checked",true);
            }else {
                $("input[tag='obj_checkbox']").prop("checked",false);
            }
        }


       function ActionSubmit(form_ele) {
           var selected_ids = [];
           $("input[tag='obj_checkbox']:checked").each(function () {   ----"input[tag='obj_checkbox']:checked"这是取到了选中数据
               selected_ids.push($(this).val());  ----这是把所有的值放到这个列表,
           })
           var selected_action = $("#action_list").val();
           console.log(selected_ids)
           console.log(selected_action)
           if (selected_ids.length == 0){
               alert("No object got selected!");
               return
           }
           if (!selected_action ){
               alert("No action got selected!");
           }


           //start submit
            var selected_ids_ele = "<input  name='selected_ids' type='hidden' value='" + selected_ids.toString() + "' >"
            $(form_ele).append(selected_ids_ele);   ---selected_ids这是所有选中的数据的id,放到表单里面,post提交,

           return true;
       }

    </script>

 前端提交了,是提交到了当前页,这是列表页,

需要加一个处理,

@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,
                                                        "previous_orderby": request.GET.get("o",''),
                                                        "search_text":request.GET.get('_q','')})

 加一个删除的action,

class BaseAdmin(object):
    list_display = []
    list_filters = []
    search_fields = []
    list_per_page = 20
    ordering = None
    filter_horizontal = []
    readonly_fields = []
    actions = ["delete_selected_objs",]
    readonly_table = False
    modelform_exclude_fields = []

    def delete_selected_objs(self,request,querysets):
        app_name = self.model._meta.app_label
        table_name = self.model._meta.model_name
        print("--->delete_selected_objs",self,request,querysets)
        if self.readonly_table:
            errors = {"readonly_table": "This table is readonly ,cannot be deleted or modified!" }
        else:
            errors = {}
        if request.POST.get("delete_confirm") == "yes":  -----这是处理提交,其他都是处理get请求的,
            if not self.readonly_table:
                querysets.delete()
            return redirect("/king_admin/%s/%s/" % (app_name,table_name))
        selected_ids =  ','.join([str(i.id) for i in querysets])   ---这是获取到所有的要删除的id。
        return render(request,"king_admin/table_obj_delete.html",{"objs":querysets,    -----这是返回到了删除页面了,注意传递的字段,
                                                              "admin_class":self,
                                                              "app_name": app_name,
                                                              "table_name": table_name,
                                                              "selected_ids":selected_ids,
                                                              "action":request._admin_action,  ---把这些参数都传递到删除页面,
                                                              "errors":errors
                                                              })

删除页面需要修改:

{% extends 'king_admin/table_index.html' %}
{% load tags %}
{% block container %}

    {% display_obj_related objs  %}

    <ul style="color: red">
    {% for k,v in errors.items %}
        <li>{{ k }}:{{ v }}</li>
    {% endfor %}
    </ul>
    <form method="post">{% csrf_token %}
        <input type="submit" class="btn btn-danger" value="Yes,I'm sure">
        <input type="hidden" value="yes" name="delete_confirm">   ----这是添加的隐藏域,
        <input type="hidden" value="{{ selected_ids }}" name="selected_ids">
        <input type="hidden" value="{{ action }}" name="action">
        <a class="btn btn-info" href="{% url 'table_objs' app_name table_name  %}">No,Take me back</a>
    </form>


{% endblock %}

 返回到列表页的时候,有两种post,一个是action的post,一个是删除点击确认之后的post返回列表页,

但是现在列表页的处理函数只有一个post,如何能解决两个post的请求?

在action函数里面做判断,在删除页面加一个删除标识,

点击删除的action之后,是调用action函数,然后函数里面是跳转到删除页面,然后删除页面提交处理post,

可以再加action了

    def test(self,request,querysets):
        print("in test",)
    test.display_name  = "测试动作"

让前端显示中文,

<div class="row" style="margin-top: 10px">
                    <form onsubmit="return ActionSubmit(this)" method="POST">{% csrf_token %}

                      <div class="col-lg-2">
                          <select id="action_list" name="action" class="form-control" style="margin-left:15px">
                              <option value="">---------</option>
                              {% for action in admin_class.actions %}
                                <option value="{{ action }}">{% get_action_verbose_name admin_class action %}</option>
                              {% endfor %}
                          </select>

                      </div>
                      <div class="col-lg-1" >
                        <button type="submit" class="btn  " >Go</button>
                      </div>
                    </form>
                </div>

tag:如果有displayname就返回这个,否则就返回action,

@register.simple_tag
def get_action_verbose_name(admin_class,action):

    action_func = getattr(admin_class,action)
    return  action_func.display_name if hasattr(action_func,'display_name') else action

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

原文地址:https://www.cnblogs.com/andy0816/p/13471775.html