CRM项目(九)

CRM项目(九)

文章目录 

1. 原生admin体验

2. 重写action

  2.1基类中添加字段

  2.2 添加默认的批量删除

  2.3 模板文件编写

    2.3.1 模板文件中显示功能

    2.3.2 模板中添加表单功能

    2.3.3 中文显示功能

  2.4 视图函数

    2.4.1 模板文件的数据发送

    2.4.2 视图函数的数据接收

  2.5 编写具体批量删除功能

    2.5.1 批量删除功能编写

    2.5.2 复用编辑页面的删除功能主页面

    2.5.3 删除数据

 

现在该来添加前面提到的Action功能了,强大的它能干什么,先来体验一下原生admin中的效果。

1. 原生admin体验

  • 默认的删除功能是可以进行批量删除的!

    • 可以在后台进行自定义功能

    CRM应用目录下的admin.py中添加:

from django.contrib import admin
from CRM import models
from django.shortcuts import render
# Register your models here.

#自定义操作
class CustomerAdmin(admin.ModelAdmin):
    list_display = ('name', 'id','qq','source','consultant','content','status','date')
    list_filter = ('source','consultant','date')
    search_fields = ('qq','name')
    raw_id_fields = ('consult_course',)
    filter_horizontal = ('tags',)
    list_editable = ('status',)
    #添加如下内容
    actions = ("test_action", )

    def test_action(self,request,arg2):
        print('test action:',self,request,arg2)
        return render(request,"king_admin/table_index.html")

效果图:

跳转到指定的页面:

2. 重写action

2.1基类中添加字段

第一件事还是跟以前一样,需要在基类中添加对应的字段选项:

king_admin_base.py文件中:

class ModelAdmin(object):
    list_display = []
    list_filter = []
    search_fields = []
    ordering = None
    filter_horizontal = []
    actions = []  #添加该字段
    list_per_page = 10

2.2 添加默认的批量删除

我还要在基类中添加默认情况下的批量删除功能,这个同原生admin中定义的方式一样。需要在基类下面定义个批量删除功能的函数。

king_admin_base.py文件中添加要定义的功能函数:

from  django.shortcuts import render

#创建基类
class ModelAdmin(object):
    list_display = []
    list_filter = []
    search_fields = []
    ordering = None
    filter_horizontal = []
    actions = ['delete_many_objects']
    list_per_page = 10


    def delete_many_objects(self, request, selected_objects):
        return render(request, 'king_admin/table_object_delete.html')

...

2.3 模板文件编写

2.3.1 模板文件中显示功能

要在模板文件中显示这个功能函数,我们必须在table_objs.html文件中添加,只需要简单的添加一些标签:

...

                  <button type="SUBMIT" class="btn btn-success">search</button>
                  </div>
                </form>
               </div>
                {# 添加action #}
                <div class="row" style="margin-top: 10px">
                      <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 }}">{{ action }}</option>
                              {% endfor %}
                          </select>
                      </div>
                      <div class="col-lg-1">
                        <button type="submit" class="btn  " >Go</button>
                      </div>
                </div>
              {#具体的表格内容展示 #}

...
View Code

 

显示效果如下:

有的朋友会问:你没有传admin_class变量?是的,这里没有必要再传了,因为在该模板文件中已经存在了!

2.3.2 模板中添加表单功能

上面只是简单的显示了功能,并没有实现具体的功能。然而实现具体的功能我们需要进行传递一些必要的值,传输这些值就需要表单组件来提供功能。

还是上面的代码,套一层表单标签即可:

 </div>
                </form>
               </div>
                {# 添加action #}
                <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 }}">{{ action }}</option>
                              {% endfor %}
                          </select>
                      </div>
                      <div class="col-lg-1">
                        <button type="submit" class="btn">Go</button>
                      </div>
                    </form>
                </div>
              {#具体的表格内容展示 #}
View Code

 

2.3.3 中文显示功能

说到中文显示,我们就不得不用到自定义标签了。但在使用之前先来看看原生的admin是怎么实现中文显示的吧:

...

    def test_action(self,request,arg2):
        print('test action:',self,request,arg2)
        return render(request,"king_admin/table_index.html")
    test_action.short_description = '测试'  #添加这行代码

...

显示效果:

开始我们自己的中文显示吧,就为我们刚刚写到默认批量删除功能添加显示中文:

...
class ModelAdmin(object):
    list_display = []
    list_filter = []
    search_fields = []
    ordering = None
    filter_horizontal = []
    actions = ['delete_many_objects']
    list_per_page = 10


    def delete_many_objects(self, request, queryset):
        return render(request, 'king_admin/table_object_delete.html')
    delete_many_objects.short_description = '批量删除'
...

 

模板文件修改如下:  

{# 添加action #}
                <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_name admin_class action %}</option>
                              {% endfor %}
                          </select>
                      </div>

templates/tags.py文件中,添加的内容如下:

...

<------------------------显示默认action中文--------------------------
@register.simple_tag
def get_action_name(admin_class, action):
    action_func = getattr(admin_class, action)
    if hasattr(action_func, 'short_description'):
        return action_func.short_description
    else:
        return action

渲染后的效果:

2.4 视图函数

上面我们已经查不到将模板文件所需要的都已经编写完毕,接下来就是数据的收发,涉及到数据的收发我们必须要用到视图。这里是在table_objs.html文件基础上添加的功能,视图中,我们同样要使用它来接收来自该模板文件的数据请求。

2.4.1 模板文件的数据发送

前面刚刚建立了表单功能,向后台提交数据就需要使用POST方式进行,同时我们还要将那些选中的checkbox中的行id一同传送到后端。

在前面建立表单的时候,已经添加了传送方式和提交的函数:<form onsubmit="return ActionSubmit(this)" method="POST">,这里将具体的提交函数编写一下:

...

        function  ActionSubmit(self) {
            var selected_ids = [];
            $("input[tag='object_checkbox']:checked").each(function () {
                selected_ids.push($(this).val());
            });
            var selected_action = $("#action_list").val();
            if  (selected_ids.length == 0){
                alert("No object got selected!");
                return;
            }
            if (!selected_action){
                alert("No action got selected!");
            }
           //添加隐藏标签,用来存储提交的数据key/value
            var selected_ids_ele = "<input  name='selected_ids' type='hidden' value='" + selected_ids.toString() + "'>";
            $(self).append(selected_ids_ele);
            return true;
        }

这些脚本同样放在该文件的最下面。

2.4.2 视图函数的数据接收

上面的数据已经发送,该接收数据了。接收数据的功能函数我们使用display_objects(request, app_name, table_name)即可,我们只需要添加几行代码:

...

def display_objects(request, app_name, table_name):
    #获取自定义的admin_class
    admin_class = site.enabled_admins[app_name][table_name]
    #数据查询
    #query_set = admin_class.model.objects.all()

    <------------------接收action数据----------------------------
    if request.method == '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)
            #将action存储在请求体中便于调用
            request._admin_action = action
            return action_func(admin_class, request, selected_objs)

...

2.5 编写具体批量删除功能

还记得之前编写的删除功能吗?这里我们要复用一下,在此基础上简单的添加一标签用来提交数据。

2.5.1 批量删除功能编写

继续填补之前编写的批量删除功能的架子,默认情况的GET请求页面获取,在king_admin_base.py中:

...
    def delete_many_objects(self, request, selected_objects):
        app_name = self.model._meta.app_label
        table_name = self.model._meta.model_name
        selected_ids = ','.join([str(i.id) for i in selected_objects])
        return render(request, 'king_admin/table_object_delete.html',{'selected_objects': selected_objects,
                                                                      'action': request._admin_action,
                                                                      'selected_ids': selected_ids,
                                                                      'app_name': app_name,
                                                                      'table_name': table_name})
    delete_many_objects.short_description = '批量删除'

 

2.5.2 复用编辑页面的删除功能主页面

table_object_delete.html文件中修改如下:

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

{% block body-content %}

    {% if not action %}
        {# 显示映射关系 #}
        {% display_object_related object_list %}
        {# 表单提交  #}
        <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">
            <a class="btn btn-info" href="{% url 'king_admin:table_object_edit' app_name table_name object_id %}">No,Take me back</a>
        </form>
    {% else %}
        {# 显示映射关系 #}
        {% display_object_related selected_objects %}
        {# 批量删除 #}
        <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="{{ action }}" name="action"/>
            <input type="hidden" value="{{ selected_ids }}" name="selected_ids"/>
            <a class="btn btn-info" href="/king_admin/{{ app_name }}/{{ table_name }}/?page={{ get_page }}">No,Take me back</a>
        </form>
    {% endif %}
{% endblock %}
View Code

 

2.5.3 删除数据

上面完成了数据的发送与接收,最后剩下的就是数据的删除:

king_admin_base.py文件的函数修改:

...
    def delete_many_objects(self, request, selected_objects):
        app_name = self.model._meta.app_label
        table_name = self.model._meta.model_name
        selected_ids = ','.join([str(i.id) for i in selected_objects])
        #添加如下判断
        if request.method == 'POST':
            if request.POST.get('delete_confirm') == 'yes':
                selected_objects.delete()
                return redirect('/king_admin/{app_name}/{table_name}'.format(app_name=app_name,
                                                                             table_name=table_name))
        return render(request, 'king_admin/table_object_delete.html',{'selected_objects': selected_objects,
                                                                      'action': request._admin_action,
                                                                      'selected_ids': selected_ids,
                                                                      'app_name': app_name,
                                                                      'table_name': table_name,
                                                                      'get_page': request.GET.get('page')})
    delete_many_objects.short_description = '批量删除'

...
View Code

效果查看:

Good!批量删除功能搞定了,同时也意味着action的告终。如果你想要实现其他功能,基本的流程就是这样的,仅供参考。

大致的思路如下:

未完待续。。。  

 

posted @ 2017-02-12 15:28  runnering  阅读(112)  评论(0)    收藏  举报