您现在的位置是: 网站首页 >Django >DjangoCRM客户关系管理 Django

【CRM客户关系管理】22.action功能开发,执行action功能,添加默认的delete action

admin2018年12月23日 15:57 Django | JavaScript | JQuery | Python 228人已围观

DjangoCRM客户关系管理简介 使用Django2.1.3+Bootstrap实现CRM系统,仿照Django Admin重写后台 Github地址:https://github.com/xyliurui/DjangoCRM Django版本:2.1.3

### 执行actions功能 #### form中增加提交函数 修改form中提交执行的操作 ```html <form method="post" onsubmit="ActionCheck(this)"> <div class="row"> <div class="col-md-3"> <select class="form-control" name="action"> <option value="">-------</option> {% for action in admin_class.actions %} <option value="{{ action }}">{{ action }}</option> {% endfor %} </select> </div> {% csrf_token %} <div class="col-md-2"> <input type="submit" value="执行" class="btn btn-primary"> </div> </div> </form> ``` #### 使用js来向form增加数据选项 - 获取执行的功能,如果没有选择,则提示; - 获取勾选的数据项;如果没有勾选,则提示; - 如果勾选了,将勾选的id放在一个序列中,转换成json格式; - 最后使用一个隐藏的input标签,添加到form内; - 提交form表单,就会提交选择的功能和勾选的数据; table_detail.html模板的所有内容如下,包含js函数`ActionCheck(ele)` ```html {% extends 'djadmin/base.html' %} {% load djadmin_tags %} {% block title %} 数据表详情 - 后台管理 {% endblock %} {% block content %} <h1 class="page-header">应用 - {{ app_name }} - {{ model_name }}</h1> <a href="{% url 'djadmin:table_add' app_name model_name %}"><button class="btn btn-primary">添加</button></a> {# queryset #} {% if admin_class.list_filter %} <p> <form class="navbar-form navbar-left"> {% for filter_field in admin_class.list_filter %} {% build_option_filter filter_field admin_class %} {% endfor %} <button type="submit" class="btn btn-primary">过滤</button> </form> </p> {% endif %} <form method="post" onsubmit="ActionCheck(this)"> <div class="row"> <div class="col-md-3"> <select class="form-control" name="action"> <option value="">-------</option> {% for action in admin_class.actions %} <option value="{{ action }}">{{ action }}</option> {% endfor %} </select> </div> {% csrf_token %} <div class="col-md-2"> <input type="submit" value="执行" class="btn btn-primary"> </div> </div> </form> <table class="table table-striped"> <thead> <tr> <th><input type="checkbox" onclick="SelectALLObjs(this)"></th> {% if admin_class.list_display %} {% for display_field in admin_class.list_display %} <th> <a href="?_order={% get_sorted_data display_field current_order_field forloop.counter0 %}{% render_filter_args admin_class %}"> {{ display_field }} {% get_sorted_arrow display_field current_order_field forloop.counter0 %} </a> </th> {% endfor %} {% else %} {% build_table_head_name admin_class %} {% endif %} <th>操作</th> <!-- {% build_table_head_name admin_class %} --> </tr> </thead> <tbody> {% for obj in queryset %} <tr> <td><input row-select="true" type="checkbox" value="{{ obj.id }}"></td> {% build_table_body obj admin_class %} <td><a href="{% url 'djadmin:table_delete' app_name model_name obj.id %}">删除</a></td> </tr> {% endfor %} </tbody> </table> <div> {% include 'includes/pagination.html' with page=queryset current_order_value=current_order_value %} </div> <div class="pagination"> <span class="step-links"> {% if queryset.has_previous %} <a href="?page=1">&laquo; first</a> <a href="?page={{ queryset.previous_page_number }}">previous</a> {% endif %} <span class="current"> Page {{ queryset.number }} of {{ queryset.paginator.num_pages }}. </span> {% if queryset.has_next %} <a href="?page={{ queryset.next_page_number }}">next</a> <a href="?page={{ queryset.paginator.num_pages }}">last &raquo;</a> {% endif %} </span> </div> <script> function SelectALLObjs(ele) { if ($(ele).prop('checked')){ $('input[row-select]').prop('checked',true) }else{ $('input[row-select]').prop('checked',false) } } function ActionCheck(ele) { let selected_action = $("select[name='action']").val(); // 获取选择的功能 let selected_objs = $("input[row-select]").filter(":checked"); // 获取下方所有勾选 console.log(selected_action); console.log(selected_objs); if (!selected_action){ alert("没有选择的执行项!"); return false } //alert(selected_objs.length); if (selected_objs.length == 0 ){ alert("没有选择数据项!"); return false } else { // 生成一个form标签,放在form里 let selected_ids = []; $.each(selected_objs, function () { console.log($(this)); selected_ids.push($(this).val()) }); console.log(selected_ids); let input_ele = "<input type='hidden' name='selected_ids' value=" + JSON.stringify(selected_ids) + ">"; $(ele).append(input_ele); } } </script> {% endblock %} ``` #### 后台处理勾选的数据和功能 修改djadmin应用的views.py,在`table_detail(request, app_name, model_name)`视图中增加POST逻辑处理 ```python @login_required def table_detail(request, app_name, model_name): """取出指定model里的数据返回到前端""" # 拿到admin_class后,通过它获取model admin_class = site.enable_admins[app_name][model_name] # print(admin_class) # 执行djadmin.py定义的注册模型类 # POST提交,djadmin actions if request.method == 'POST': if request.POST.get('action') and request.POST.get('selected_ids'): # 获取action,这个action是从djadmin中actions列表中定义的 selected_action = request.POST.get('action') # 获取选中的id import json selected_ids =json.loads(request.POST.get('selected_ids')) print(selected_ids) # 列表类型:['7', '6', '3'] # 获取所有选中id的对象 selected_objs = admin_class.model.objects.filter(id__in=selected_ids) # 获取djadmin中定义的actions函数 admin_action_func = getattr(admin_class, selected_action) # 讲查询集执行action的功能 admin_action_func(request, selected_objs) print('执行{}的功能!'.format(selected_action)) # 防止刷新网页提交,使用跳转 return redirect(reverse('djadmin:table_detail', args=(app_name, model_name))) queryset = admin_class.model.objects.all().order_by('-id') # print(queryset) # 进行过滤 queryset, filter_conditions = get_filter_result(request, queryset) # 将过滤字典保存到全局注册类中 admin_class.filter_conditions = filter_conditions # 搜索 queryset, keyword = get_search_result(request, queryset, admin_class) admin_class.search_keyword = keyword # 将搜索字符串保存到全局类中 # 排序,返回排序的结果和排序的字段字典 queryset, current_order_field = get_order_result(request, queryset, admin_class) # print(current_order_field) # {'consult_content': '4'} # 如果有排序,保存排序的值,用于模板中在分页模块显示 if current_order_field.values(): current_order_value = list(current_order_field.values())[0] else: current_order_value = '' # 查询集结果分页 # paginator = Paginator(queryset, 10) # Show 10 contacts per page paginator = Paginator(queryset, admin_class.list_per_page) # 获取djadmin.py中自定义的分页数量 page = request.GET.get('page') try: queryset = paginator.get_page(page) except PageNotAnInteger: queryset = paginator.get_page(1) except EmptyPage: queryset = paginator.get_page(paginator.num_pages) return render(request, 'djadmin/table_detail.html', locals()) ``` 现在就可以批量执行action操作了 例如现在的数据内容如下 ![BLOG_20181223_160025_41](/media/blog/images/2018/12/BLOG_20181223_160025_41.png "博客图集BLOG_20181223_160025_41.png") 然后点击执行,就会修改已勾选的数据 ![BLOG_20181223_160005_95](/media/blog/images/2018/12/BLOG_20181223_160005_95.png "博客图集BLOG_20181223_160005_95.png") ### 添加默认的delete action #### 添加default_actions默认删除方法 直接在djadmin_base.py父类中添加默认删除方法,crm应用的djadmin.py继承后就自动拥有该方法 - 在djadmin_base.py中添加一个`delete_selected_objs`方法,该方法会渲染table_delete.html显示删除的哪些对象 - 添加一个`default_actions = ['delete_selected_objs']`,不能直接加到actions里面,因为子类会覆盖父类的actions - 利用`__init__`方法,把`default_actions`里面的值添加到`actions`里面 ```python # djadmin/djadmin_base.py class BaseDjAdmin(object): def __init__(self): self.actions.extend(self.default_actions) # 创建实例进行初始化的时候,会将default_actions并到actions中 list_display = [] list_filter = [] search_fields = [] readonly_fields = [] filter_horizontal = [] list_per_page = 5 actions = [] default_actions = ['delete_selected_objs'] def delete_selected_objs(self, request, queryset): import json from django.shortcuts import render print('跳转到删除函数') selected_ids = json.dumps([item.id for item in queryset]) action = 'delete_selected_objs' return render(request, 'djadmin/table_delete_objs.html', { 'admin_class': self, # self就是admin_class 'action': action, 'objs': queryset, 'selected_ids': selected_ids }) ``` 例如我们访问 http://127.0.0.1:8000/djadmin/crm/userprofile/ ![BLOG_20181223_155951_81](/media/blog/images/2018/12/BLOG_20181223_155951_81.png "博客图集BLOG_20181223_155951_81.png") 会出现多个删除,就需要进行有的判断 ```python class BaseDjAdmin(object): def __init__(self): if 'delete_selected_objs' not in self.actions: # 如果注册多个应用,不进行判断,就会创建多个删除 self.actions.extend(self.default_actions) # 创建实例进行初始化的时候,会将default_actions并到actions中 # 。。。。。。 ``` ![BLOG_20181223_155929_74](/media/blog/images/2018/12/BLOG_20181223_155929_74.png "博客图集BLOG_20181223_155929_74.png") #### 创建删除对象显示详情确认模板 在djadmin/templates/djadmin创建**table_delete_objs.html**,可以参考table_delete.html模板的写法 观察`table_detail`视图,需要选择的`action`、`selected_ids`,所以上面的类方法需要返回这些值。 另外定义一个`delete_confirm`,这个用于删除操作时的判断,如果得到这个值就执行删除,否则,显示删除对象显示详情模板 ```html {% extends 'djadmin/base.html' %} {% load djadmin_tags %} {% block title %} 数据表删除 - 后台管理 {% endblock %} {% block content %} <h2 class="page-header">{{ model_name }}</h2> <h3 class="page-header alert alert-danger">你确定要删除吗?</h3> {% for obj in objs %} {% display_all_related_objs obj as all_related_obj_eles %} {{ all_related_obj_eles|safe }} {# 需要加上|safe,否则会直接显示源代码 #} {% endfor %} <form method="post"> {% csrf_token %} <input class="hidden" value="yes" name="delete_confirm"> <input class="hidden" value="{{ action }}" name="action"> <input class="hidden" value="{{ selected_ids }}" name="selected_ids"> <input type="submit" class="btn btn-danger" value="确认删除"> </form> {% endblock %} ``` #### 视图中判断删除返回模板 修改djadmin应用下的views.py中的`table_detail`视图函数,对POST逻辑机型判断,因为执行和删除都是post动作,且同时存在在该视图中 如果选择的action是`delete_selected_objs`则进入删除对象的父类`BaseDjAdmin.delete_selected_objs` ```python # POST提交,djadmin actions if request.method == 'POST': if request.POST.get('action') and request.POST.get('selected_ids'): # 获取action,这个action是从djadmin中actions列表中定义的 selected_action = request.POST.get('action') # 获取选中的id import json print(request.POST.get('selected_ids')) # json数据["7","6","3"] selected_ids =json.loads(request.POST.get('selected_ids')) print(selected_ids) # 列表类型:['7', '6', '3'] # 获取所有选中id的对象 selected_objs = admin_class.model.objects.filter(id__in=selected_ids) # 获取djadmin中定义的actions函数 admin_action_func = getattr(admin_class, selected_action) # 默认删除功能 if selected_action == 'delete_selected_objs': print('执行{}删除功能'.format(selected_action)) # 默认情况下显示table_delete.objs.html的内容 return admin_action_func(request, selected_objs) # 返回admin_action_func执行方法不用再跳回来 # 将查询集执行action的功能 admin_action_func(request, selected_objs) print('执行{}的功能!'.format(selected_action)) # 防止刷新网页提交,使用跳转 return redirect(reverse('djadmin:table_detail', args=(app_name, model_name))) ``` 访问 http://127.0.0.1:8000/djadmin/crm/customerinfo/ 添加一些测试数据,选择`delete_selected_objs`,勾选一些数据,然后点击执行 ![BLOG_20181223_155916_20](/media/blog/images/2018/12/BLOG_20181223_155916_20.png "博客图集BLOG_20181223_155916_20.png") 点击执行 ![BLOG_20181223_155858_65](/media/blog/images/2018/12/BLOG_20181223_155858_65.png "博客图集BLOG_20181223_155858_65.png") #### 视图中处理删除功能逻辑 点击确认删除,会将`action`、`selected_ids`、`delete_selected_objs`参数传递到后端进行处理 ```python # POST提交,djadmin actions if request.method == 'POST': if request.POST.get('action') and request.POST.get('selected_ids'): # 获取action,这个action是从djadmin中actions列表中定义的 selected_action = request.POST.get('action') # 获取选中的id import json selected_ids =json.loads(request.POST.get('selected_ids')) print(selected_ids) # 列表类型:['7', '6', '3'] # 获取所有选中id的对象 selected_objs = admin_class.model.objects.filter(id__in=selected_ids) # 获取djadmin中定义的actions函数 admin_action_func = getattr(admin_class, selected_action) # 默认删除功能 if selected_action == 'delete_selected_objs': print('执行{}删除功能'.format(selected_action)) # 提交的数据进行删除 if request.POST.get('delete_confirm') == 'yes': admin_class.model.objects.filter(id__in=selected_ids).delete() return redirect(reverse('djadmin:table_detail', args=(app_name, model_name))) # 默认情况下显示table_delete.objs.html的内容 return admin_action_func(request, selected_objs) # 返回admin_action_func执行方法不用再跳回来 # 将查询集执行action的功能 admin_action_func(request, selected_objs) print('执行{}的功能!'.format(selected_action)) # 防止刷新网页提交,使用跳转 return redirect(reverse('djadmin:table_detail', args=(app_name, model_name))) ``` ![BLOG_20181223_155849_24](/media/blog/images/2018/12/BLOG_20181223_155849_24.png "博客图集BLOG_20181223_155849_24.png") 点击删除后,会跳回列表页面,逻辑成功。

很赞哦! (1)

文章交流

  • emoji
0人参与,0条评论

当前用户

未登录,点击   登录

站点信息

  • 建站时间:网站已运行588天
  • 系统信息:Linux
  • 后台程序:Python: 3.6.6
  • 网站框架:Django: 2.2.9
  • 文章统计:222 篇
  • 文章评论:40 条
  • 腾讯分析网站概况-腾讯分析
  • 百度统计网站概况-百度统计
  • 微信公众号:扫描二维码,关注我们
返回
顶部
标题 换行 登录
网站