![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #admin.py 2 3 # ————————01PerfectCRM基本配置ADMIN———————— 4 5 from django.contrib import admin 6 # Register your models here. 7 from crm import models #从crm导入models 8 9 # ————————24PerfectCRM实现King_admin自定义操作数据———————— 10 from django.shortcuts import render 11 # ————————24PerfectCRM实现King_admin自定义操作数据———————— 12 13 # ————————04PerfectCRM实现King_admin注册功能———————— 14 class CustomerAdmin(admin.ModelAdmin):#定制Djanago admin 15 list_display = ('id','qq','source','consultant','content','date')#显示字段表头 16 # ————————11PerfectCRM实现King_admin分页显示条数———————— 17 list_per_page = 2 #分页条数 18 # ————————11PerfectCRM实现King_admin分页显示条数———————— 19 # ————————16PerfectCRM实现King_admin日期过滤———————— 20 # ————————15PerfectCRM实现King_admin多条件过滤———————— 21 # 过滤器(可以包含ManyToManyField) (注意加 逗号 , ) 22 # list_filter = ('source','consultant','consult_courses',) 23 list_filter = ('date','source','consultant','consult_courses',) 24 # ————————15PerfectCRM实现King_admin多条件过滤———————— 25 # ————————16PerfectCRM实现King_admin日期过滤———————— 26 # ————————18PerfectCRM实现King_admin搜索关键字———————— 27 #搜索(不能包含CharField)(注意加 逗号 , ) 28 search_fields = ('name','qq',) 29 # ————————18PerfectCRM实现King_admin搜索关键字———————— 30 31 # ————————26PerfectCRM实现King_admin自定义排序———————— 32 ordering = ['-qq'] #自定义排序,默认'-id' 33 # ————————26PerfectCRM实现King_admin自定义排序———————— 34 35 # ————————27PerfectCRM实现King_admin编辑复选框———————— 36 filter_horizontal = ('tags',) #复选框 37 # ————————27PerfectCRM实现King_admin编辑复选框———————— 38 39 40 41 # ————————24PerfectCRM实现King_admin自定义操作数据———————— 42 # from django.shortcuts import render 43 actions = ['test_actions',]#定制功能 #测试返回到一个新页面 44 def test_actions(self,request,arg2):#对应的函数 #request类自己的请求 #arg2类的内容 45 return render(request,"king_admin/table_index.html") 46 test_actions.short_description = "测试显示中文" 47 # ————————24PerfectCRM实现King_admin自定义操作数据———————— 48 49 50 # ————————04PerfectCRM实现King_admin注册功能———————— 51 52 #注册到 Django Admin里 53 admin.site.register(models.Branch) #01校区表 54 admin.site.register(models.ClassList) #02班级表 55 admin.site.register(models.Course) #03课程表,可以报名那些课程 56 57 # ————————04PerfectCRM实现King_admin注册功能———————— 58 # admin.site.register(models.Customer) #04客户信息表 59 admin.site.register(models.Customer,CustomerAdmin) #04客户信息表 60 # ————————04PerfectCRM实现King_admin注册功能———————— 61 62 admin.site.register(models.CustomerFollowUp) #05客户跟进表 63 admin.site.register(models.Enrollment) #06学员报名信息表 64 admin.site.register(models.Payment) #07缴费记录表 65 admin.site.register(models.CourseRecord) #08每节课上课纪录表 66 admin.site.register(models.StudyRecord) #09学习纪录 67 admin.site.register(models.UserProfile) #10账号表 68 admin.site.register(models.Role) #11角色表 69 admin.site.register(models.Tag) #12标签表 70 71 ''' 72 Django Admin里账号密码重置方法 73 #运行 Terminal 74 75 python manage.py createsuperuser 76 77 Username : admin 78 Email address: admin@qq.com 79 Password: admin123456 80 Password (again): admin123456 81 82 83 英文转中文方法 84 到settings.py里修改 85 # LANGUAGE_CODE = 'en-us' 86 LANGUAGE_CODE = 'zh-Hans' 87 ''' 88 89 # ————————01PerfectCRM基本配置ADMIN————————
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 # kingadmin.py 2 # ————————04PerfectCRM实现King_admin注册功能———————— 3 from crm import models 4 #print("kingadmin crm",models.Customer) 5 6 # ————————05PerfectCRM实现King_admin注册功能获取内存———————— 7 # from king_admin.base_admin import register,BaseAdmin 8 from king_admin.base_admin import site,BaseAdmin 9 # ————————05PerfectCRM实现King_admin注册功能获取内存———————— 10 11 # ————————24PerfectCRM实现King_admin自定义操作数据———————— 12 from django.shortcuts import render 13 # ————————24PerfectCRM实现King_admin自定义操作数据———————— 14 15 #04客户信息表 16 class CustomerAdmin(BaseAdmin):#定制Djanago admin 17 list_display = ('id', 'qq', 'source', 'consultant', 'content', 'date') # 显示字段表头 18 19 # ————————11PerfectCRM实现King_admin分页显示条数———————— 20 list_per_page = 2 #分页条数 # 默认分页条数10 21 # ————————11PerfectCRM实现King_admin分页显示条数———————— 22 23 # ————————16PerfectCRM实现King_admin日期过滤———————— 24 # ————————15PerfectCRM实现King_admin多条件过滤———————— 25 # 过滤器(可以包含ManyToManyField) (注意加 逗号 , ) 26 # list_filter = ('source','consultant','consult_courses',) 27 list_filter = ('date','source','consultant','consult_courses',) 28 # ————————15PerfectCRM实现King_admin多条件过滤———————— 29 # ————————16PerfectCRM实现King_admin日期过滤———————— 30 31 # ————————18PerfectCRM实现King_admin搜索关键字———————— 32 #搜索(不能包含CharField)(注意加 逗号 , ) 33 search_fields = ('name','qq',) 34 # ————————18PerfectCRM实现King_admin搜索关键字———————— 35 36 # ————————26PerfectCRM实现King_admin自定义排序———————— 37 ordering = '-qq' #自定义排序,默认'-id' 38 # ————————26PerfectCRM实现King_admin自定义排序———————— 39 40 # ————————27PerfectCRM实现King_admin编辑复选框———————— 41 filter_horizontal = ('tags',) #复选框 42 # ————————27PerfectCRM实现King_admin编辑复选框———————— 43 44 # ————————24PerfectCRM实现King_admin自定义操作数据———————— 45 # from django.shortcuts import render 46 actions = ['test_actions',]#定制功能 #测试返回到一个新页面 47 def test_actions(self,request,arg2):#对应的函数 #request类自己的请求 #arg2类的内容 48 return render(request,"king_admin/table_index.html") 49 test_actions.short_description = "测试显示中文" 50 # ————————24PerfectCRM实现King_admin自定义操作数据———————— 51 52 53 54 # ————————05PerfectCRM实现King_admin注册功能获取内存———————— 55 # register(models.Customer,CustomerAdmin) 56 # register(models.CourseRecord) 57 site.register(models.Customer,CustomerAdmin) 58 site.register(models.CourseRecord) 59 # ————————05PerfectCRM实现King_admin注册功能获取内存———————— 60 61 # ————————04PerfectCRM实现King_admin注册功能————————
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #base_admin.py 2 3 4 # ————————24PerfectCRM实现King_admin自定义操作数据———————— 5 from django.shortcuts import render,redirect 6 # ————————24PerfectCRM实现King_admin自定义操作数据———————— 7 8 # ————————04PerfectCRM实现King_admin注册功能———————— 9 10 #Django admin 注册功能的形式 11 # sites = { 12 # 'crm':{ 13 # 'customers':CustomerAdmin, 14 # 'customerfollowup':CustomerFollowUPAdmin, 15 # } 16 # } 17 18 class AdminRegisterException(Exception): #自定义异常 19 def __init__(self,msg): 20 self.message = msg 21 22 class BaseAdmin(object):#自定义方法 23 list_display = () #显示的字段(不能包含ManyToManyField) 24 25 # ————————11PerfectCRM实现King_admin分页显示条数———————— 26 list_per_page = 10 # 默认分页条数10 27 # ————————11PerfectCRM实现King_admin分页显示条数———————— 28 29 # ————————15PerfectCRM实现King_admin多条件过滤———————— 30 list_filter = () # 过滤器(可以包含ManyToManyField) (注意加 逗号 , ) 31 # ————————15PerfectCRM实现King_admin多条件过滤———————— 32 33 # ————————18PerfectCRM实现King_admin搜索关键字———————— 34 search_fields = () #搜索(不能包含CharField)(注意加 逗号 , ) 35 # ————————18PerfectCRM实现King_admin搜索关键字———————— 36 37 # ————————26PerfectCRM实现King_admin自定义排序———————— 38 ordering = None #自定义排序 39 # ————————26PerfectCRM实现King_admin自定义排序———————— 40 41 # ————————27PerfectCRM实现King_admin编辑复选框———————— 42 filter_horizontal = []#复选框 43 # ————————27PerfectCRM实现King_admin编辑复选框———————— 44 45 # ————————24PerfectCRM实现King_admin自定义操作数据———————— 46 actions = []#自定功能 47 48 default_actions = ["delete_selected",] #默认删除的函数 49 #默认删除的函数 50 def delete_selected(self,request,queryset): 51 # from django.shortcuts import render, redirect 52 print("goint to delete ",queryset) 53 app_name=self.model._meta.app_label#app名 54 model_name=self.model._meta.model_name#表名 55 objs=queryset#类对象 56 action=request._admin_action 57 print(action,'<-------action') 58 if request.POST.get('delete_confirm')=='yes': #{#table_delete.html#} 59 queryset.delete() 60 return redirect('/king_admin/%s/%s/'%(app_name,model_name)) 61 selected_ids=','.join([str(i.id) for i in queryset]) 62 print(selected_ids,'<---selected_ids') 63 objs=queryset 64 return render(request,"king_admin/table_delete.html", locals()) #返回删除页 65 delete_selected.short_description = "默认批量删除" 66 # ————————24PerfectCRM实现King_admin自定义操作数据———————— 67 68 69 # ————————05PerfectCRM实现King_admin注册功能获取内存———————— 70 class AdminSite(object): 71 def __init__(self): 72 self.registered_sites = {} #传到views 里调用 73 def register(self,model,admin_class=None): #默认值None 使用 BaseAdmin 74 app_name = model._meta.app_label#用内置方法获取 APP名字 (crm) 75 model_name = model._meta.model_name#用内置方法获取 表名 (Customer) 76 if app_name not in self.registered_sites: 77 self.registered_sites[app_name] = {} #创建 crm={} 78 if model_name in self.registered_sites[app_name]: 79 raise AdminRegisterException("app [%s] model [%s] has already registered!异常" 80 %(app_name,model_name))#自定义异常, 81 if not admin_class: 82 admin_class = BaseAdmin #默认值None 使用 BaseAdmin 83 # self.registered_sites[app_name][model_name] = admin_class #注册APP 84 # site = AdminSite() # 实例化类 单例模式 85 86 87 # ————————05PerfectCRM实现King_admin注册功能获取内存———————— 88 #registered_sites {'crm': {'customer': <class 'crm.kingadmin.CustomerAdmin'>, 'courserecord': <class 'kingadmin.base_admin.BaseAdmin'>}} 89 #把类名放到class的对象里,然后通过class的对象传到前端 90 # admin_class.model = model 91 # self.registered_sites[app_name][model_name] = admin_class #注册APP 92 # 93 # site = AdminSite() #实例化类 单例模式 94 # ————————05PerfectCRM实现King_admin注册功能获取内存———————— 95 96 # ————————06PerfectCRM实现King_admin注册功能获取内存优化处理———————— 97 #没有实例化会使用同一个内存地址 98 admin_obj = admin_class() #先实例化 99 admin_obj.model = model #参数赋值给实例 100 self.registered_sites[app_name][model_name] = admin_obj#注册APP 101 #实例化后,调用会使用不同的内存地址 102 103 site = AdminSite() #实例化类 单例模式 104 # ————————06PerfectCRM实现King_admin注册功能获取内存优化处理———————— 105 106 # registered_sites={} 107 # def register(model,admin_class=None): #默认值None 使用 BaseAdmin 108 # app_name = model._meta.app_label#用内置方法获取 APP名字 (crm) 109 # model_name = model._meta.model_name#用内置方法获取 表名 (Customer) 110 # if app_name not in registered_sites: 111 # registered_sites[app_name] = {} #创建 crm={} 112 # if model_name in registered_sites[app_name]: 113 # raise AdminRegisterException("app [%s] model [%s] has already registered!异常" 114 # %(app_name,model_name))#自定义异常 115 # if not admin_class: 116 # admin_class = BaseAdmin #默认值None 使用class BaseAdmin 117 # registered_sites[app_name][model_name] = admin_class #注册APP 118 119 # ————————05PerfectCRM实现King_admin注册功能获取内存———————— 120 121 # ————————04PerfectCRM实现King_admin注册功能————————
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 {#table_change.html#} 2 {## ————————19PerfectCRM实现King_admin数据修改————————#} 3 {#{% extends "king_master/king_index.html" %}#} 4 {##} 5 {#{% load kingadmin_tags %}#} 6 {#{% block right-container-content %}#} 7 {##} 8 {# {{ obj_form }}#} 9 {##} 10 {#{% endblock %}#} 11 {## ————————19PerfectCRM实现King_admin数据修改————————#} 12 13 {## ————————20PerfectCRM实现King_admin数据修改美化————————#} 14 {% extends 'king_master/king_index.html' %} {#继承模板#} 15 {% load kingadmin_tags %} {#通过自己定义标签获取中文,Django中利用filter与simple_tag为前端自定义函数的实现方法#} 16 17 18 19 20 {% block right-container-content %} 21 <div class="row" style="margin-bottom: 20px" > 22 <ol class="breadcrumb"> 23 <li><a href="/king_admin/">主页</a></li> 24 <li><a href="/king_admin/{% get_app_name admin_obj.model %}/">{% get_app_name admin_obj.model %}</a></li> 25 <li><a href="/king_admin/{% get_app_name admin_obj.model %}/{% get_model_name admin_obj.model %}/"> 26 {% get_model_verbose_name admin_obj.model %} </a></li> 27 {% if not admin_obj.is_add_form %} {# 新建时 ForeignKey不能实例化 #} 28 <li class="active">{{ obj_form.instance }}</li> {# 修改时 实例化 #} 29 {% endif %} 30 </ol> 31 {## ————————25PerfectCRM实现King_admin添加出错修复————————#} 32 {# <h4>修改:{% get_model_verbose_name admin_obj.model %}</h4>#} 33 34 {% block Tops %} 35 <div class="panel panel-info"> 36 <h4 style='color: red'>修改: {% get_model_verbose_name admin_obj.model %}</h4> 37 </div> 38 {% endblock %} 39 {## ————————25PerfectCRM实现King_admin添加出错修复————————#} 40 </div> 41 42 <div class="row"> 43 {{ obj_form.errors }} 44 45 {## ————————27PerfectCRM实现King_admin编辑复选框————————#} 46 {#<form class="form-horizontal" method="post" >{% csrf_token %}#} 47 <form class="form-horizontal" method="post" onsubmit="return BeforeFormSubmit(this);">{% csrf_token %} 48 {## ————————27PerfectCRM实现King_admin编辑复选框————————#} 49 50 {% for field in obj_form %} 51 <div class="form-group"> 52 <label class="col-sm-2 " style="font-weight: normal"> {#字体#} 53 {% if field.field.required %} {#required判断是不是必须填写#} 54 <b>{{ field.label }}</b> 55 {% else %} 56 {{ field.label }} 57 {% endif %} 58 59 </label> 60 <div class="col-sm-10" > 61 <span style="color: red;">{{ field.errors }}</span> 62 63 64 65 {## ————————27PerfectCRM实现King_admin编辑复选框————————#} 66 {# {{ field }}#} 67 {% if field.name in admin_obj.filter_horizontal %} <!-- 水平--><!-- 判断是否复选框--> 68 {% get_m2m_chosen_objs admin_obj field.name obj_form.instance as m2m_chosen_objs %} <!--当前对象已经选中的字段名--> 69 <!-- 左边待选框--> 70 <div class="col-md-6"> 71 <!-- 取所有的内容--> 72 {% get_m2m_available_objs admin_obj field.name as m2m_available_objs %} 73 {# <input type="text" oninput="FuzzSearch(this,'id_{{ field.name }}_from')" class="form-control">#} 74 <!-- 字段名--> 75 <select multiple field_name="{{ field.name }}" class="form-control filter-select-box" id="id_{{ field.name }}_from" > 76 <!-- 字段名 是否为不能修改--> 77 {% if field.name in admin_obj.readonly_fields and not admin_obj.is_add_form %} 78 {% for obj in m2m_available_objs %} 79 {% if obj not in m2m_chosen_objs %}<!--不在当象已经选中的字段名 才显示--> 80 <option value="{{ obj.id }}" disabled>{{ obj }}</option> 81 {% endif %} 82 {% endfor %} 83 {% else %} 84 {% for obj in m2m_available_objs %} 85 {% if obj not in m2m_chosen_objs %}<!--不在当象已经选中的字段名 才显示--> 86 <option value="{{ obj.id }}" ondblclick="MoveEleTo(this,'id_{{ field.name }}_to')">{{ obj }}</option> 87 {% endif %} 88 {% endfor %} 89 {% endif %} 90 </select> 91 </div> 92 <!-- 中间箭头--> 93 <div class="col-md-1"> 94 <div><h4 style='color: #00ff06'>待选 -> </h4></div> 95 <div><h4 style='color: #8dffc5'>双击选择 </h4></div> 96 <div><h4 style='color: #ff0003'> <- 已选 </h4></div> 97 </div> 98 99 <!-- 右边已选框--> 100 <div class="col-md-5"> 101 <select m2m_right="yes" name="{{ field.name }}" multiple field_name="{{ field.name }}" class="form-control" id="id_{{ field.name }}_to"> 102 {% if field.name in admin_obj.readonly_fields and not admin_obj.is_add_form %} 103 {% for obj in m2m_chosen_objs %} 104 <option value="{{ obj.id }}" disabled>{{ obj }}</option> 105 {% endfor %} 106 {% else %} 107 108 {% for obj in m2m_chosen_objs %} 109 <option value="{{ obj.id }}" ondblclick="MoveEleTo(this,'id_{{ field.name }}_from')">{{ obj }}</option> 110 {% endfor %} 111 {% endif %} 112 </select> 113 114 </div> 115 116 {% else %} 117 {{ field }} <span style="color: #bce8f1"> {{ field.help_text }}</span> 118 {# <span style="color:red">{{ field.errors }}</span>#} 119 {% endif %} <!-- 判断是否复选框--> 120 {## ————————27PerfectCRM实现King_admin编辑复选框————————#} 121 122 123 124 </div> 125 </div> 126 {% endfor %} 127 128 {## ————————25PerfectCRM实现King_admin添加出错修复————————#} 129 {## ————————23PerfectCRM实现King_admin数据删除————————#} 130 {# <a class="btn btn-danger" href="{% url 'table_delete' app_name model_name obj_form.instance.id %}">删除</a>#} 131 {## ————————23PerfectCRM实现King_admin数据删除————————#} 132 {# <input type="submit" value="保存" class="pull-right btn btn-info" > {#放右边#} 133 134 <div class="form-group"> 135 {% block del %} 136 <div class="col-sm-2"> 137 <a class="btn btn-danger" href="{% url 'table_delete' app_name model_name obj_form.instance.id %}">删除</a> 138 </div> 139 {% endblock %} 140 <div class="col-sm-10"> 141 <input type="submit" value="保存" class="pull-right btn btn-info"> 142 </div> 143 </div> 144 {## ————————25PerfectCRM实现King_admin添加出错修复————————#} 145 146 </form> 147 </div> 148 149 150 151 152 153 {% endblock %} 154 {## ————————20PerfectCRM实现King_admin数据修改美化————————#}
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 {#king_base.html#} 2 {## ————————02PerfectCRM创建ADMIN页面————————#} 3 {#模板文件 king_base.html#} 4 <!DOCTYPE html> 5 <html lang="zh-CN"> 6 <head> 7 {# <meta> 元素可提供有关页面的元信息(meta-information),比如针对搜索引擎和更新频度的描述和关键词。#} 8 {# <meta> 标签位于文档的头部,不包含任何内容。<meta> 标签的属性定义了与文档相关联的名称/值对。#} 9 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 10 <meta http-equiv="X-UA-Compatible" content="IE=edge"> 11 <meta name="viewport" content="width=device-width, initial-scale=1"> 12 <meta name="description" content=""> 13 <meta name="author" content=""> 14 15 <link rel="icon" href="/static/king_img/king_logo.jpg">{# icon,指的是图标 #} 16 <title>KingAdmin</title> {# 页面头部显示#} 17 18 {# 使用link来调用外部的css文件#} 19 <link rel="stylesheet" href="/static/king_css/bootstrap.css" /> {#导航栏样式#} 20 <link rel="stylesheet" href="/static/king_css/dashboard.css" /> {#指示板样式#} 21 22 {## ————————27PerfectCRM实现King_admin编辑复选框————————#} 23 <link rel="stylesheet" href="/static/king_css/king_admin_change.css" /> {#编辑复选框样式#} 24 {## ————————27PerfectCRM实现King_admin编辑复选框————————#} 25 26 27 28 </head> 29 30 <body> 31 32 {% block body %}{#自定义内容 body#}{% endblock %} 33 34 {# 将纯JavaScript的语句另外保存在一个"*.js"的文件中,需要时再调用。#} 35 <script src="/static/king_js/jquery.js"></script> {# jQuery 是一个 JavaScript库,极大地简化了 JavaScript 编程。#} 36 <script src="/static/king_js/bootstrap.js"></script> {#指示板JS事件#} 37 38 {## ————————24PerfectCRM实现King_admin自定义操作数据————————#} 39 <script src="/static/king_js/king_admin_js.js"></script> {#自定义JS事件#} 40 {## ————————24PerfectCRM实现King_admin自定义操作数据————————#} 41 42 {## ————————27PerfectCRM实现King_admin编辑复选框————————#} 43 <script src="/static/king_js/king_admin_change.js"></script> {#编辑复选框JS事件#} 44 {## ————————27PerfectCRM实现King_admin编辑复选框————————#} 45 46 47 </body> 48 </html> 49 50 {## ————————02PerfectCRM创建ADMIN页面————————#}
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /*king_admin_change.css*/ 2 3 4 /*# ————————27PerfectCRM实现King_admin编辑复选框————————*/ 5 .filter-select-box{ 6 height: 230px;!important; 7 width:100%; 8 } 9 10 /*# ————————27PerfectCRM实现King_admin编辑复选框————————*/
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 // king_admin_change.js 2 // # ————————27PerfectCRM实现King_admin编辑复选框———————— 3 function BeforeFormSubmit(form_ele) { 4 5 console.log(form_ele); 6 //$('form input[disabled]').prop("disabled", false);//修改为可提交 7 $("form").find("[disabled]").removeAttr("disabled");//修改为 可提交 8 9 $('select[m2m_right="yes"] option').prop('selected', true); 10 11 return true; 12 } 13 14 15 function MoveEleTo(from_ele, target_ele_id) { 16 //move options from from_ele to target ele 17 var field_name = $(from_ele).parent().attr("field_name");//获option名 18 if (target_ele_id.endsWith('_from')) {//判断是否 19 var new_target_id = "id_" + field_name + "_to"; 20 } else { 21 var new_target_id = "id_" + field_name + "_from"; 22 } 23 //创建一个新标签 24 var opt_ele = "<option value='" + $(from_ele).val() + "' ondblclick=MoveEleTo(this,'" + new_target_id + "') >" + $(from_ele).text() + "</option>"; 25 $("#" + target_ele_id).append(opt_ele);//添加到另一边选框 26 $(from_ele).remove();//移除选中的 27 28 } 29 30 // # ————————27PerfectCRM实现King_admin编辑复选框————————
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #kingadmin_tags.py 2 3 # ————————06PerfectCRM实现King_admin注册功能获取内存优化处理———————— 4 5 # # 因为前端禁止使用下划线开头(_meta.verbose_name ),所以通过后端处理后返回前端。 6 # from django import template #模板 7 # register = template.Library() #模板库 8 # 9 # @register.simple_tag #Django中利用filter与simple_tag为前端自定义函数的实现方法 10 # def get_app_name(model_obj): 11 # 12 # # ————————06PerfectCRM实现King_admin注册功能获取内存优化处理———————— 13 # # return model_obj._meta.verbose_name_plural 14 # ''' 15 # #判断 数据库 里如果有 verbose_name 或者 verbose_name_plural 就 调用 如果都没有 就使用默认的(英文) 16 # class Meta: 17 # verbose_name = "04客户信息表" #在 Django Admin 里 表名显示中文 但是会加s 18 # verbose_name_plural = "04客户信息表" #在 Django Admin 里 表名显示中文 不会加s 19 # ''' 20 # model_name = model_obj._meta.verbose_name_plural if model_obj._meta.verbose_name else model_obj._meta.verbose_name_plural 21 # if not model_name: 22 # model_name = model_obj._meta.model_name 23 # 24 # return model_name 25 # ————————06PerfectCRM实现King_admin注册功能获取内存优化处理———————— 26 27 # ————————06PerfectCRM实现King_admin注册功能获取内存优化处理———————— 28 29 # ————————07PerfectCRM实现King_admin显示注册的表———————— 30 #因为前端禁止使用下划线开头(_meta.verbose_name ),所以通过后端处理后返回前端。 31 from django import template #模板 32 register = template.Library() #模板库 33 34 35 36 @register.simple_tag #Django中利用filter与simple_tag为前端自定义函数的实现方法 37 def get_model_verbose_name(model_obj): 38 ''' 39 #判断 数据库 里如果有 verbose_name 或者 verbose_name_plural 就 调用 如果都没有 就使用默认的(英文) 40 class Meta: 41 verbose_name = "04客户信息表" #在 Django Admin 里 表名显示中文 但是会加s 42 verbose_name_plural = "04客户信息表" #在 Django Admin 里 表名显示中文 不会加s 43 ''' 44 model_name = model_obj._meta.verbose_name_plural if model_obj._meta.verbose_name else model_obj._meta.verbose_name_plural 45 if not model_name: 46 model_name = model_obj._meta.model_name 47 return model_name 48 49 @register.simple_tag 50 def get_model_name(model_obj): 51 return model_obj._meta.model_name 52 @register.simple_tag 53 def get_app_name(model_obj): 54 return model_obj._meta.app_label 55 # ————————07PerfectCRM实现King_admin显示注册的表———————— 56 57 58 # ————————09PerfectCRM实现King_admin显示注册表的内容———————— 59 from django.utils.safestring import mark_safe #使用mark_safe函数标记后,django将不再对该函数的内容进行转义 60 @register.simple_tag 61 def build_table_row(admin_obj,obj):#通过kingadmin_tags在后台处理 再传到前端 62 row_ele = "" #为了生成一整行返回前端 63 if admin_obj.list_display:#如果不为空,有在crm/kingadmin.py注册site.register(models.Customer,CustomerAdmin) 64 65 # ————————19PerfectCRM实现King_admin数据修改———————— 66 #循环所有 要显示 的字符串 进行反射 展示 字段 67 # for column in admin_obj.list_display: #循环base_admin里class BaseAdmin下list_display = () 68 for index, column in enumerate(admin_obj.list_display): # 转为列表取 下标 , 字段名 69 # ————————19PerfectCRM实现King_admin数据修改———————— 70 71 column_obj = obj._meta.get_field(column)#遍历获取 传进的参数对象 72 if column_obj.choices:#判断如果字段有choices属性 73 #获取choices的字符串(外健) 74 get_column_data = getattr(obj,"get_%s_display" % column) #反射,传进的参数对象,拼接字段 75 column_data = get_column_data()#函数,拿到数据 76 else: 77 column_data = getattr(obj, column)#反射, 78 # ————————10PerfectCRM实现King_admin日期优化———————— 79 if type(column_data).__name__ == 'datetime': 80 column_data = column_data.strftime('%Y-%m-%d %H-%M-%S') 81 # ————————10PerfectCRM实现King_admin日期优化———————— 82 83 # ————————19PerfectCRM实现King_admin数据修改———————— 84 85 if index == 0: #首列 86 # 生成一个链接 跳转到编辑页面 #Format参数是一个格式字符串(%s升级版) 87 td_ele = '''<td><a href="/king_admin/{app_name}/{model_name}/{obj_id}/change/">{column_data}</a> </td>''' 88 .format(app_name=admin_obj.model._meta.app_label, 89 model_name=admin_obj.model._meta.model_name, 90 obj_id=obj.id, 91 column_data=column_data) 92 else: 93 td_ele = '''<td>%s</td>''' % column_data 94 # td_ele = '''<td>%s</td>''' % column_data #把反射来的值 拼接字符串 生成<td> 95 # ————————19PerfectCRM实现King_admin数据修改———————— 96 row_ele += td_ele #把 <td> 拼接到上面到空字符串 97 else: 98 row_ele +="<td>%s</td>" %obj #把<td>拼接到上面到空字符串,crm/models.py里 def __str__(self):的返回值 99 return mark_safe(row_ele) #使用mark_safe函数标记后,django将不再对该函数的内容进行转义 100 # ————————09PerfectCRM实现King_admin显示注册表的内容———————— 101 102 103 # ————————13PerfectCRM实现King_admin分页页数———————— 104 #分页功能kingadmin/templates/kingadmin/table_data_list.html里 <a href="?page={{ page }}{% generate_filter_url admin_obj %}">{{ page }} 105 @register.simple_tag 106 def generate_filter_url(admin_obj): #拼接URL 107 url = '' 108 for k,v in admin_obj.filter_condtions.items(): 109 url += "&%s=%s" %(k,v ) 110 return url 111 # ————————13PerfectCRM实现King_admin分页页数———————— 112 113 # ————————14PerfectCRM实现King_admin分页的省略显示———————— 114 #分页的省略显示 115 @register.simple_tag 116 def pag_omit(request,admin_obj):#传入当前页面值 117 rest=''#大字符串 118 # ————————18PerfectCRM实现King_admin搜索关键字———————— 119 search_key = get_search_key(request) # 搜索 120 # ————————18PerfectCRM实现King_admin搜索关键字———————— 121 # ————————17PerfectCRM实现King_admin单列排序———————— 122 order_by_url = generate_order_by_url(request) # 排序 123 # ————————17PerfectCRM实现King_admin单列排序———————— 124 # ————————15PerfectCRM实现King_admin多条件过滤———————— 125 filters = generate_filter_url(admin_obj) # 分页 126 # ————————15PerfectCRM实现King_admin多条件过滤———————— 127 add_tags=False#标志位 128 for pages in admin_obj.querysets.paginator.page_range: 129 # 前两页 或 后 两页 或 当前页的前后页 130 if pages < 3 or pages>admin_obj.querysets.paginator.num_pages -2 or abs(admin_obj.querysets.number -pages) <=2: 131 #样式 132 add_tags=False 133 ele_class='' #颜色 134 if pages == admin_obj.querysets.number: #--如果是当前页码,颜色加深 不进链接跳转-- 135 ele_class="active" #颜色加深 136 # ————————18PerfectCRM实现King_admin搜索关键字———————— 137 # ————————17PerfectCRM实现King_admin单列排序———————— 138 # ————————15PerfectCRM实现King_admin多条件过滤———————— 139 # rest+='''<li class="%s"><a href="?page=%s">%s</a></li>'''%(ele_class,pages,pages) #--拼接URL-- 140 # rest+='''<li class="%s"><a href="?page=%s%s">%s</a></li>'''%(ele_class,pages,filters,pages) #--拼接URL-- 141 # ————————15PerfectCRM实现King_admin多条件过滤———————— 142 # rest+='''<li class="%s"><a href="?page=%s%s%s">%s<span class="sr-only">(current)</span></a></li>''' 143 # %(ele_class,pages,order_by_url,filters,pages) 144 # ————————17PerfectCRM实现King_admin单列排序———————— 145 rest+='''<li class="%s"><a href="?page=%s%s%s&_q=%s">%s<span class="sr-only">(current)</span></a></li>''' 146 %(ele_class,pages,order_by_url,filters,search_key,pages) 147 # ————————18PerfectCRM实现King_admin搜索关键字———————— 148 else:#其他的用省略号表示 149 if add_tags==False:#如果不是标志位的页面 150 rest+='<li><a>...</a></li>' 151 add_tags=True#标志位为真 152 return mark_safe(rest) #使用mark_safe函数标记后,django将不再对该函数的内容进行转义 153 154 # ————————14PerfectCRM实现King_admin分页的省略显示———————— 155 156 157 158 # # ————————15PerfectCRM实现King_admin多条件过滤———————— 159 # #多条件过滤 table_data_list.html 传递参数 160 # @register.simple_tag 161 # def get_filter_field (filter_column,admin_obj): 162 # print("admin obj",admin_obj.model ,filter_column) 163 # field_obj = admin_obj.model._meta.get_field(filter_column)#调用内置方法 164 # select_ele = """<select name="%s"> """ %filter_column #拼接成下拉框返回 165 # for choice in field_obj.get_choices():#循环获取crm/models里class Customer(models.Model):下source_choices = ((0,'转介绍'), 166 # selected_condtion = admin_obj.filter_condtions.get(filter_column) 167 # if selected_condtion != None: #if None, 没有过滤这个条件 168 # print("heoe....",filter_column,selected_condtion,type(selected_condtion))#类型是 整数 169 # if selected_condtion == str(choice[0]): #就是选择的这个条件,整数转字符串 170 # selected = "selected" 171 # else: 172 # selected = "" 173 # else: 174 # selected = "" 175 # 176 # #在前端把几个条件提交到后台,后台拿着条件变成一个字典,然后进行过滤,把数据返回前端,并且把条件作为字典返回后端,因为要在前端显示已经过滤的条件。 177 # option_ele = """<option value="%s" %s>%s</option> """ % (choice[0],selected,choice[1]) 178 # select_ele +=option_ele 179 # select_ele += "</select>" 180 # return mark_safe(select_ele) 181 # # ————————15PerfectCRM实现King_admin多条件过滤———————— 182 183 # # ————————16PerfectCRM实现King_admin日期过滤———————— 184 from django.utils.timezone import datetime,timedelta 185 @register.simple_tag 186 def get_filter_field (filter_column,admin_obj): 187 select_ele = """<select name='{filter_column}'><option value="">---------</option>""" #标签 字符串 #拼接成下拉框返回 188 field_obj = admin_obj.model._meta.get_field(filter_column)#调用内置方法 189 selected = '' 190 if field_obj.choices: 191 for choice_item in field_obj.choices: 192 if admin_obj.filter_condtions.get(filter_column) == str(choice_item[0]): 193 selected = "selected" 194 select_ele += """<option value="%s" %s>%s</option> """ % (choice_item[0], selected, choice_item[1]) 195 selected = "" 196 197 if type(field_obj).__name__ in "ForeignKey": 198 for choice_item in field_obj.get_choices()[1:]: 199 if admin_obj.filter_condtions.get(filter_column)== str(choice_item[0]): # 就是选择的这个条件,整数转字符串 200 selected = "selected" 201 select_ele += """<option value="%s" %s>%s</option> """ % (choice_item[0], selected, choice_item[1]) 202 selected='' 203 204 if type(field_obj).__name__ in ['DateTimeField', 'DateField']: # 如果是时间格式 205 date_els = [] # 日期条件项 206 today_ele = datetime.now().date() # 今天日期 207 date_els.append(['今天', today_ele]) # 今天 208 date_els.append(['昨天', today_ele - timedelta(days=1)]) # 昨天 209 date_els.append(['近7天', today_ele - timedelta(days=7)]) # 一周 210 date_els.append(['近30天', today_ele - timedelta(days=30)]) # 三十 211 date_els.append(['本月', today_ele.replace(day=1)]) # 本月 212 date_els.append(['近90天', today_ele - timedelta(days=90)]) # 90天 213 date_els.append(['近365天', today_ele - timedelta(days=365)]) # 365天 214 date_els.append(['本年', today_ele.replace(month=1, day=1)]) ##今年 215 216 for choice_item in date_els: 217 if admin_obj.filter_condtions.get("%s__gte" %filter_column)==str(choice_item[1]): 218 selected = 'selected' 219 select_ele += """<option value="%s" %s>%s</option> """ % (choice_item[1], selected, choice_item[0]) 220 selected = '' 221 filter_column_name = "%s__gte" %filter_column 222 else: 223 filter_column_name = filter_column 224 225 select_ele += "</select>" 226 select_ele=select_ele.format(filter_column=filter_column_name)#格式化时间的判断条件 227 return mark_safe(select_ele) 228 # ————————16PerfectCRM实现King_admin日期过滤———————— 229 230 # ————————17PerfectCRM实现King_admin单列排序———————— 231 # kingadmin排序功能 232 @register.simple_tag 233 def get_orderby_key(request,column): 234 current_order_by_key = request.GET.get("_o") 235 # ————————18PerfectCRM实现King_admin搜索关键字———————— 236 search_key = request.GET.get("_q") 237 if search_key != None: 238 if current_order_by_key != None: #如果不为空 #肯定有某列被排序了 239 if current_order_by_key == column: # 判断是否相等 #当前这列正在被排序 240 if column.startswith("-"): #startsWith是String类中的一个方法,用来检测某字符串是否以另一个字符串开始,返回值为boolean类型 241 return column.strip("-") #strip去掉 文本中句子开头与结尾的符号的 242 else: 243 return "-%s&_q=%s" % (column, search_key) 244 return "%s&_q=%s" % (column, search_key) 245 else: 246 # ————————18PerfectCRM实现King_admin搜索关键字———————— 247 if current_order_by_key != None: #如果不为空 #肯定有某列被排序了 248 if current_order_by_key == column: # 判断是否相等 #当前这列正在被排序 249 if column.startswith("-"): #startsWith是String类中的一个方法,用来检测某字符串是否以另一个字符串开始,返回值为boolean类型 250 return column.strip("-") #strip去掉 文本中句子开头与结尾的符号的 251 else: 252 return "-%s"%column 253 # else: 254 # return column 255 # else: 256 # return column 257 return column #同上4句 258 # kingadmin排序功能 259 260 # kingadmin排序功能 显示排序图标 261 # @register.simple_tag 262 # def display_order_by_icon(request, column): 263 # current_order_by_key = request.GET.get("_o") 264 # if current_order_by_key != None: #肯定有某列被排序了 265 # if current_order_by_key.strip("-") == column: ## 当前这列正在被排序 266 # if current_order_by_key.startswith("-"): 267 # icon = "fa-arrow-up" 268 # else: 269 # icon = "fa-arrow-down" 270 # ele = """<i class="fa %s" aria-hidden="true"></i>""" % icon 271 # return mark_safe(ele) 272 # return '' 273 # kingadmin排序功能 显示排序图标 274 @register.simple_tag 275 def display_order_by_icon(request, column): 276 current_order_by_key = request.GET.get("_o") 277 if current_order_by_key != None: #肯定有某列被排序了 278 if current_order_by_key.strip("-") == column: # 当前这列正在被排序 #strip去掉 文本中句子开头与结尾的符号的 279 if current_order_by_key.startswith("-"): #startsWith是String类中的一个方法,用来检测某字符串是否以另一个字符串开始,返回值为boolean类型 280 icon = "▲" 281 else: 282 icon = "▼" 283 ele = """<i style='color: red'>%s</i>""" % icon 284 return mark_safe(ele) 285 return '' #防止出现 None 286 # kingadmin排序功能 显示排序图标 287 288 # kingadmin排序功能 # 过滤后排序功能 #} 289 @register.simple_tag 290 def get_current_orderby_key(request): #注意生成的URL问题 291 #获取当前正在排序的字段名 #<input type="hidden" name="_o" value="{% get_current_orderby_key request %}"> 292 current_order_by_key = request.GET.get("_o") 293 return current_order_by_key or '' 294 # kingadmin排序功能 # 过滤后排序功能 #} 295 296 # kingadmin排序功能 # 过滤后排序功能 # 排序分页 297 @register.simple_tag 298 def generate_order_by_url (request): 299 current_order_by_key = request.GET.get("_o") 300 if current_order_by_key != None: # 肯定有某列被排序了 301 return "&_o=%s" % current_order_by_key 302 return '' 303 # kingadmin排序功能 # 过滤后排序功能 # 排序分页 304 # ————————17PerfectCRM实现King_admin单列排序———————— 305 306 # ————————18PerfectCRM实现King_admin搜索关键字———————— 307 @register.simple_tag 308 def get_search_key(request): # 搜索框里保留搜索值 309 search_key = request.GET.get("_q") 310 return search_key or '' 311 # ————————18PerfectCRM实现King_admin搜索关键字———————— 312 313 # ————————23PerfectCRM实现King_admin数据删除———————— 314 # <-------------------获取删除映射关系-------------------------------- 315 @register.simple_tag 316 def display_all_related_obj(objs): 317 # 取出对象及所有相关联的数据 318 from django.db.models.query import QuerySet 319 if type(objs) != QuerySet: 320 objs = [objs, ] 321 if objs: 322 model_class = objs[0]._meta.model # 取表对象 323 model_name = objs[0]._meta.model_name # 取表名 324 return mark_safe(recursive_related_objs_lookup(objs)) 325 # <-----------------递归获取映射关系-------------------------------- 326 def recursive_related_objs_lookup(objs, name=None, conn_batch_size=0): 327 name = set() 328 print(name) 329 print('传递过来的objs:', objs) 330 # 开始标签的拼接 331 ul_ele = "<ul style='color: blue'>" 332 for obj in objs: 333 li_ele = '''<li>{0}:{1}</li>'''.format(obj._meta.verbose_name, obj.__str__().strip("<>")) 334 print('str:', obj.__str__(), '类型:', type(obj.__str__())) 335 print('关联的表的自定表名:', li_ele) 336 ul_ele += li_ele 337 print('拼接li_ele:', ul_ele) 338 # 映射关系处理 339 # <---------------------------特殊关联处理----------------------------------- 340 # 多对多关系 341 for m2m_field in obj._meta.local_many_to_many: # local_many_to_many返回列表,many_to_many返回元祖 342 print('--开始循环反射-多对多-关系处理--') 343 sub_ul_ele = "<ul style='color: red'>" 344 m2m_field_obj = getattr(obj, m2m_field.name) # 反射 如果有选项 345 print('反射选项:', m2m_field_obj) 346 347 for m2m_data in m2m_field_obj.select_related(): 348 print('开始循环多对多标签拼接:', m2m_data) 349 350 sub_li_ele = '''<li>{0}:{1}</li>'''.format(m2m_field.verbose_name, m2m_data.__str__().strip("<>")) 351 sub_ul_ele += sub_li_ele 352 sub_ul_ele += '</ul>' 353 ul_ele += sub_ul_ele 354 print('生成完整 多对多 标签..:', ul_ele) 355 # <---------------------------外健关联处理------------------------------------ 356 for related_obj in obj._meta.related_objects: 357 print('--开始-外健关联-处理--') 358 if hasattr(obj, related_obj.get_accessor_name()): 359 print('--判断对象中是否包含反查属性--') 360 accessor_obj = getattr(obj, related_obj.get_accessor_name()) 361 print('获取反查对应的对象: ') 362 if hasattr(accessor_obj, 'select_related'): 363 print('--判断有没有获取数据的方法或属性-- ') 364 target_object = accessor_obj.select_related() 365 print('获取数据的方法或属性: ', target_object) 366 367 if 'ManyToManyRel' in related_obj.__repr__(): 368 print('--开始-外健关联-多对多-处理--.') 369 370 # 生成UL 371 sub_ul_ele = '<ul style="color: green">' 372 for data in target_object: 373 print('开始循环-外健关联-标签拼接...', data) 374 sub_li_ele = '''<li>{0}:{1}</li>'''.format(data._meta.verbose_name, 375 data.__str__().strip("<>")) 376 sub_ul_ele += sub_li_ele 377 sub_ul_ele += '</ul>' 378 ul_ele += sub_ul_ele 379 print('-外健关联-生成完整标签:', ul_ele) 380 # <---------------递归处理------------------- 381 if len(target_object) != conn_batch_size: 382 print('--有下级对象存在,进行-递归-循环--') 383 names = target_object.__str__() 384 print(names, type(names)) 385 if names == name: 386 print('--如果是自己关联自己,就不递归了--') 387 ul_ele += '</ul>' 388 return ul_ele 389 else: 390 print('--防止无限递归+1--') 391 conn_batch_size = conn_batch_size + 1 392 node = recursive_related_objs_lookup(target_object, name=names, 393 conn_batch_size=conn_batch_size) 394 ul_ele += node 395 396 # <---------------由于使用递归,下面的标签样会发生重复,就不需要使用了-------------------- 397 else: 398 print('外健关联 一对一:', accessor_obj) 399 target_object = accessor_obj 400 print("外健关联 一对一:", target_object, '属性:', type(target_object)) 401 402 ul_ele += '</ul>' 403 return ul_ele 404 405 # ————————23PerfectCRM实现King_admin数据删除———————— 406 407 408 # ————————24PerfectCRM实现King_admin自定义操作数据———————— 409 #自定制 actions功能 显示 410 @register.simple_tag 411 def get_admin_actions(admin_obj): 412 #选择功能 413 options = "<option class='form-control' value='-1'>-------</option>"#默认为空 414 actions = admin_obj.default_actions + admin_obj.actions #默认加自定制 415 print('默认加自定制',actions) 416 for action in actions: 417 action_func = getattr(admin_obj,action)#功能方法 #反射 418 if hasattr(action_func,"short_description"):#反射 如有自定义的名称执行函数方法 419 action_name = action_func.short_description#等于自定义的名称 #显示中文 420 else: 421 action_name = action#等于函数名称 422 options += """<option value="{action_func_name}">{action_name}</option> """.format(action_func_name=action, action_name=action_name) 423 return mark_safe(options) 424 # ————————24PerfectCRM实现King_admin自定义操作数据———————— 425 426 427 428 # ————————27PerfectCRM实现King_admin编辑复选框———————— 429 # 复选 框内容待选数据 430 @register.simple_tag 431 def get_m2m_available_objs(admin_obj, field_name): 432 '''返回m2m左侧所有待选数据''' 433 # c= admin_obj.model.tags.rel.model.objects.all() 434 # print('c',c) 435 # m2m_objs= admin_obj.model.tags.rel.model.objects.all() 436 # print('m2m_objs',m2m_objs) 437 m2m_model = getattr(admin_obj.model, field_name).rel # 复选框对象 438 m2m_objs = m2m_model.model.objects.all() # 获取到复选框所有内容 439 return m2m_objs 440 441 442 # 复选 框内容已选中数据 443 @register.simple_tag 444 def get_m2m_chosen_objs(admin_obj, field_name, obj): 445 """ 446 返回已选中的列表 447 :param admin_obj: 448 :param field_name: 449 :param obj: 数据对象 450 :return: 451 """ 452 # print(["--->obj",obj]) 453 if obj.id: 454 return getattr(obj, field_name).all() # 返回所有的内容 455 return [] # 没有数据为返回空 创建新的记录使用 456 # ————————27PerfectCRM实现King_admin编辑复选框————————