Django项目:CRM(客户关系管理系统)--65--55PerfectCRM实现CRM客户报名状态颜色变化
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 # ————————28PerfectCRM实现King_admin编辑限制———————— 16 from django.forms import ValidationError 17 from django.shortcuts import render,redirect 18 # ————————28PerfectCRM实现King_admin编辑限制———————— 19 20 #04客户信息表 21 class CustomerAdmin(BaseAdmin):#定制Djanago admin 22 # ————————54PerfectCRM实现CRM客户报名链接———————— 23 # list_display = ('id', 'qq', 'source', 'consultant', 'content', 'date') # 显示字段表头 24 list_display = ('id', 'qq', 'source', 'consultant', 'content', 'date','status','enroll') # 显示字段表头 25 # ————————54PerfectCRM实现CRM客户报名链接———————— 26 # ————————11PerfectCRM实现King_admin分页显示条数———————— 27 list_per_page = 2 #分页条数 # 默认分页条数10 28 # ————————11PerfectCRM实现King_admin分页显示条数———————— 29 # ————————16PerfectCRM实现King_admin日期过滤———————— 30 # ————————15PerfectCRM实现King_admin多条件过滤———————— 31 # 过滤器(可以包含ManyToManyField) (注意加 逗号 , ) 32 # list_filter = ('source','consultant','consult_courses',) 33 list_filter = ('date','source','consultant','consult_courses',) 34 # ————————15PerfectCRM实现King_admin多条件过滤———————— 35 # ————————16PerfectCRM实现King_admin日期过滤———————— 36 # ————————18PerfectCRM实现King_admin搜索关键字———————— 37 #搜索(不能包含CharField)(注意加 逗号 , ) 38 search_fields = ('name','qq',) 39 # ————————18PerfectCRM实现King_admin搜索关键字———————— 40 # ————————26PerfectCRM实现King_admin自定义排序———————— 41 ordering = '-qq' #自定义排序,默认'-id' 42 # ————————26PerfectCRM实现King_admin自定义排序———————— 43 # ————————27PerfectCRM实现King_admin编辑复选框———————— 44 filter_horizontal = ('tags',) #复选框 45 # ————————27PerfectCRM实现King_admin编辑复选框———————— 46 # ————————33PerfectCRM实现King_admin编辑整张表限制———————— 47 readonly_table=True#默认表单不锁定 48 # ————————33PerfectCRM实现King_admin编辑整张表限制———————— 49 50 # ————————55PerfectCRM实现CRM客户报名状态颜色变化———————— 51 colored_fields = { 52 'status':{'已报名':"rgba(145, 255, 0, 0.78)", 53 '未报名':"#ddd"},} 54 # ————————55PerfectCRM实现CRM客户报名状态颜色变化———————— 55 56 # ————————54PerfectCRM实现CRM客户报名链接———————— 57 def enroll(self): 58 '''报名''' 59 print("customize field enroll",self) 60 link_name = "报名" 61 if self.instance.status == 0: 62 link_name = "报名新课程" 63 return '''<a target="_blank" class="btn-link" href="/bpm/customer/%s/enrollment/">点击%s</a> ''' % (self.instance.id,link_name) 64 # url(r'^customer/(\d+)/enrollment/$', sales_views.enrollment, name="enrollment"), # 客户招生#报名流程一 下一步 65 # target属性用于表示所链接文件打开到的位置 #记住,“”内的文字只是表示一个对象的名子。 66 enroll.display_name = "报名链接" 67 # ————————54PerfectCRM实现CRM客户报名链接———————— 68 69 70 71 # ————————24PerfectCRM实现King_admin自定义操作数据———————— 72 # from django.shortcuts import render 73 actions = ['test_actions',]#定制功能 #测试返回到一个新页面 74 def test_actions(self,request,arg2):#对应的函数 #request类自己的请求 #arg2类的内容 75 return render(request,"king_admin/table_index.html") 76 test_actions.short_description = "测试显示中文" 77 # ————————24PerfectCRM实现King_admin自定义操作数据———————— 78 79 # ————————28PerfectCRM实现King_admin编辑限制———————— 80 # ————————31PerfectCRM实现King_admin编辑多对多限制———————— 81 # readonly_fields = ('qq', 'consultant',) # 不可修改 82 readonly_fields = ('qq', 'consultant','tags',) # 不可修改 83 # ————————31PerfectCRM实现King_admin编辑多对多限制———————— 84 85 # ————————29PerfectCRM实现King_admin编辑自定义限制———————— 86 def default_form_validation(self,obj): 87 print('validation:制定的',obj.cleaned_data) 88 consult_course=obj.cleaned_data.get('content','')#自制验证字段 89 if len(consult_course)<10: 90 return ValidationError(#添加错误信息 返回 91 ("该字段%(field)s 咨询内容记录不能少于10个字符"), 92 code='invalid', 93 params={'field':'content',}, 94 ) 95 # ————————29PerfectCRM实现King_admin编辑自定义限制———————— 96 97 # ————————28PerfectCRM实现King_admin编辑限制———————— 98 99 # ————————30PerfectCRM实现King_admin编辑自定义字段验证———————— 100 def clean_name(self,obj,*args,**kwargs):#名称验证 单个 101 name=obj.cleaned_data['name'] 102 if not name: 103 obj.add_error('name','不能为空!') 104 return ValidationError(#添加错误信息 返回 105 ("%(field)s:该字段 不能为空"), 106 code='invalid', 107 params={'field':'name',}, 108 ) 109 elif len(name)<5: 110 obj.add_error('name','不能小于5个字符!') 111 #return ValidationError('',) 112 return ValidationError(#添加错误信息 返回 113 ("%(field)s:该字段 不能小于5个字符!"), 114 code='invalid', 115 params={'field':'name',}, 116 ) 117 # ————————30PerfectCRM实现King_admin编辑自定义字段验证———————— 118 119 # ————————34PerfectCRM实现CRM自定义用户———————— 120 #10账号表 121 class UserProfileAdmin(BaseAdmin):#定制Djanago admin 122 list_display = ('id', 'email', 'name') # 显示字段表头 123 124 # ————————36PerfectCRM实现King_admin密码修改———————— 125 readonly_fields = ('password',) # 不可修改,限制 126 filter_horizontal = ('user_permissions','groups') #复选框 127 modelform_exclude_fields=['last_login']#排除#不显示 #自增日期 #base_admin.py #forms.py 128 # ————————36PerfectCRM实现King_admin密码修改———————— 129 130 site.register(models.UserProfile, UserProfileAdmin) 131 # ————————34PerfectCRM实现CRM自定义用户———————— 132 133 # ————————05PerfectCRM实现King_admin注册功能获取内存———————— 134 # register(models.Customer,CustomerAdmin) 135 # register(models.CourseRecord) 136 site.register(models.Customer,CustomerAdmin) 137 site.register(models.CourseRecord) 138 # ————————05PerfectCRM实现King_admin注册功能获取内存———————— 139 140 # ————————04PerfectCRM实现King_admin注册功能————————
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 # ————————54PerfectCRM实现CRM客户报名链接———————— 104 from django.utils.safestring import mark_safe #使用mark_safe函数标记后,django将不再对该函数的内容进行转义 105 from django.core.exceptions import FieldDoesNotExist 106 @register.simple_tag 107 # ————————56PerfectCRM实现CRM客户首列进入更改页优化路径———————— 108 # def build_table_row(admin_obj,obj):#通过kingadmin_tags在后台处理 再传到前端 109 def build_table_row(admin_obj,obj,request): # 通过kingadmin_tags在后台处理 再传到前端 110 # ————————56PerfectCRM实现CRM客户首列进入更改页优化路径———————— 111 112 row_ele = "" #为了生成一整行返回前端 113 # ————————54PerfectCRM实现CRM客户报名链接———————— 114 column_not=[]#表示不是表中字段列表 115 # ————————54PerfectCRM实现CRM客户报名链接———————— 116 117 if admin_obj.list_display:#如果不为空,有在crm/kingadmin.py注册site.register(models.Customer,CustomerAdmin) 118 # ————————19PerfectCRM实现King_admin数据修改———————— 119 #循环所有 要显示 的字符串 进行反射 展示 字段 120 # for column in admin_obj.list_display: #循环base_admin里class BaseAdmin下list_display = () 121 for index, column in enumerate(admin_obj.list_display): # 转为列表取 下标 , 字段名 122 # ————————19PerfectCRM实现King_admin数据修改———————— 123 # ————————54PerfectCRM实现CRM客户报名链接———————— 124 try: #获取表中的字段 125 # ————————54PerfectCRM实现CRM客户报名链接———————— 126 127 column_obj = obj._meta.get_field(column)#遍历获取 传进的参数对象 128 if column_obj.choices:#判断如果字段有choices属性 129 #获取choices的字符串(外健) 130 get_column_data = getattr(obj,"get_%s_display" % column) #反射,传进的参数对象,拼接字段 131 column_data = get_column_data()#函数,拿到数据 132 else: 133 column_data = getattr(obj, column)#反射, 134 # ————————10PerfectCRM实现King_admin日期优化———————— 135 if type(column_data).__name__ == 'datetime': 136 column_data = column_data.strftime('%Y-%m-%d %H-%M-%S') 137 # ————————10PerfectCRM实现King_admin日期优化———————— 138 139 140 # ————————19PerfectCRM实现King_admin数据修改———————— 141 if index == 0: #首列 142 # 生成一个链接 跳转到编辑页面 #Format参数是一个格式字符串(%s升级版) 143 td_ele = '''<td><a href="/king_admin/{app_name}/{model_name}/{obj_id}/change/">{column_data}</a> </td>'''\ 144 .format(app_name=admin_obj.model._meta.app_label, 145 model_name=admin_obj.model._meta.model_name, 146 obj_id=obj.id, 147 column_data=column_data) 148 # ————————55PerfectCRM实现CRM客户报名状态颜色变化———————— 149 if column in admin_obj.colored_fields: #特定字段需要显示颜色 #如果admin_obj有配置colored_fields 150 color_dic = admin_obj.colored_fields[column] #获取配置#字段名# 'status':{'已报名':"rgba(145, 255, 0, 0.78)", 151 if column_data in color_dic: #如果#已报名#有在配置里 152 td_ele = "<td style='background-color:%s'>%s</td>" % (color_dic[column_data],column_data) #颜色#已报名 153 else: 154 td_ele = "<td>%s</td>" % column_data 155 # ————————55PerfectCRM实现CRM客户报名状态颜色变化———————— 156 157 else: 158 td_ele = '''<td>%s</td>''' % column_data 159 # td_ele = '''<td>%s</td>''' % column_data #把反射来的值 拼接字符串 生成<td> 160 # ————————19PerfectCRM实现King_admin数据修改———————— 161 # ————————54PerfectCRM实现CRM客户报名链接———————— 162 # admin_obj.column_not = False #表示是表中字段 163 except FieldDoesNotExist as e: # 如果没有获取到 164 if hasattr(admin_obj, column): # 从自定义的函数中取值 165 column_func = getattr(admin_obj, column) 166 admin_obj.instance = obj # 对象加入 167 168 column_not.append(column) # 加入非表中字段列表, 169 admin_obj.column_not = column_not # 对象加入 170 column_data = column_func() 171 print('column_data', column_data) 172 td_ele = '''<td>%s</td>''' % column_data 173 # ————————54PerfectCRM实现CRM客户报名链接———————— 174 row_ele += td_ele #把 <td> 拼接到上面到空字符串 175 else: 176 row_ele +="<td>%s</td>" %obj #把<td>拼接到上面到空字符串,crm/models.py里 def __str__(self):的返回值 177 return mark_safe(row_ele) #使用mark_safe函数标记后,django将不再对该函数的内容进行转义 178 # ————————54PerfectCRM实现CRM客户报名链接———————— 179 # ————————54PerfectCRM实现CRM客户报名链接———————— 180 ##表中自定verbose_name列名 181 @register.simple_tag 182 def verbose_name_set(admin_obj,column): 183 try: 184 verbose_name=admin_obj.model._meta.get_field(column).verbose_name.upper()#获取别名 185 print(verbose_name,'verbose_name_set') 186 print(admin_obj.model._meta,'all') 187 except FieldDoesNotExist as e: 188 verbose_name=getattr(admin_obj,column).display_name.upper() 189 return verbose_name 190 # ————————54PerfectCRM实现CRM客户报名链接———————— 191 192 193 194 # ————————13PerfectCRM实现King_admin分页页数———————— 195 #分页功能kingadmin/templates/kingadmin/table_data_list.html里 <a href="?page={{ page }}{% generate_filter_url admin_obj %}">{{ page }} 196 @register.simple_tag 197 def generate_filter_url(admin_obj): #拼接URL 198 url = '' 199 for k,v in admin_obj.filter_condtions.items(): 200 url += "&%s=%s" %(k,v ) 201 return url 202 # ————————13PerfectCRM实现King_admin分页页数———————— 203 204 # ————————14PerfectCRM实现King_admin分页的省略显示———————— 205 #分页的省略显示 206 @register.simple_tag 207 def pag_omit(request,admin_obj):#传入当前页面值 208 rest=''#大字符串 209 # ————————18PerfectCRM实现King_admin搜索关键字———————— 210 search_key = get_search_key(request) # 搜索 211 # ————————18PerfectCRM实现King_admin搜索关键字———————— 212 # ————————17PerfectCRM实现King_admin单列排序———————— 213 order_by_url = generate_order_by_url(request) # 排序 214 # ————————17PerfectCRM实现King_admin单列排序———————— 215 # ————————15PerfectCRM实现King_admin多条件过滤———————— 216 filters = generate_filter_url(admin_obj) # 分页 217 # ————————15PerfectCRM实现King_admin多条件过滤———————— 218 add_tags=False#标志位 219 for pages in admin_obj.querysets.paginator.page_range: 220 # 前两页 或 后 两页 或 当前页的前后页 221 if pages < 3 or pages>admin_obj.querysets.paginator.num_pages -2 or abs(admin_obj.querysets.number -pages) <=2: 222 #样式 223 add_tags=False 224 ele_class='' #颜色 225 if pages == admin_obj.querysets.number: #--如果是当前页码,颜色加深 不进链接跳转-- 226 ele_class="active" #颜色加深 227 # ————————18PerfectCRM实现King_admin搜索关键字———————— 228 # ————————17PerfectCRM实现King_admin单列排序———————— 229 # ————————15PerfectCRM实现King_admin多条件过滤———————— 230 # rest+='''<li class="%s"><a href="?page=%s">%s</a></li>'''%(ele_class,pages,pages) #--拼接URL-- 231 # rest+='''<li class="%s"><a href="?page=%s%s">%s</a></li>'''%(ele_class,pages,filters,pages) #--拼接URL-- 232 # ————————15PerfectCRM实现King_admin多条件过滤———————— 233 # rest+='''<li class="%s"><a href="?page=%s%s%s">%s<span class="sr-only">(current)</span></a></li>'''\ 234 # %(ele_class,pages,order_by_url,filters,pages) 235 # ————————17PerfectCRM实现King_admin单列排序———————— 236 rest+='''<li class="%s"><a href="?page=%s%s%s&_q=%s">%s<span class="sr-only">(current)</span></a></li>'''\ 237 %(ele_class,pages,order_by_url,filters,search_key,pages) 238 # ————————18PerfectCRM实现King_admin搜索关键字———————— 239 else:#其他的用省略号表示 240 if add_tags==False:#如果不是标志位的页面 241 rest+='<li><a>...</a></li>' 242 add_tags=True#标志位为真 243 return mark_safe(rest) #使用mark_safe函数标记后,django将不再对该函数的内容进行转义 244 245 # ————————14PerfectCRM实现King_admin分页的省略显示———————— 246 247 248 249 # # ————————15PerfectCRM实现King_admin多条件过滤———————— 250 # #多条件过滤 table_data_list.html 传递参数 251 # @register.simple_tag 252 # def get_filter_field (filter_column,admin_obj): 253 # print("admin obj",admin_obj.model ,filter_column) 254 # field_obj = admin_obj.model._meta.get_field(filter_column)#调用内置方法 255 # select_ele = """<select name="%s"> """ %filter_column #拼接成下拉框返回 256 # for choice in field_obj.get_choices():#循环获取crm/models里class Customer(models.Model):下source_choices = ((0,'转介绍'), 257 # selected_condtion = admin_obj.filter_condtions.get(filter_column) 258 # if selected_condtion != None: #if None, 没有过滤这个条件 259 # print("heoe....",filter_column,selected_condtion,type(selected_condtion))#类型是 整数 260 # if selected_condtion == str(choice[0]): #就是选择的这个条件,整数转字符串 261 # selected = "selected" 262 # else: 263 # selected = "" 264 # else: 265 # selected = "" 266 # 267 # #在前端把几个条件提交到后台,后台拿着条件变成一个字典,然后进行过滤,把数据返回前端,并且把条件作为字典返回后端,因为要在前端显示已经过滤的条件。 268 # option_ele = """<option value="%s" %s>%s</option> """ % (choice[0],selected,choice[1]) 269 # select_ele +=option_ele 270 # select_ele += "</select>" 271 # return mark_safe(select_ele) 272 # # ————————15PerfectCRM实现King_admin多条件过滤———————— 273 274 # # ————————16PerfectCRM实现King_admin日期过滤———————— 275 from django.utils.timezone import datetime,timedelta 276 @register.simple_tag 277 def get_filter_field (filter_column,admin_obj): 278 select_ele = """<select name='{filter_column}'><option value="">---------</option>""" #标签 字符串 #拼接成下拉框返回 279 field_obj = admin_obj.model._meta.get_field(filter_column)#调用内置方法 280 selected = '' 281 if field_obj.choices: 282 for choice_item in field_obj.choices: 283 if admin_obj.filter_condtions.get(filter_column) == str(choice_item[0]): 284 selected = "selected" 285 select_ele += """<option value="%s" %s>%s</option> """ % (choice_item[0], selected, choice_item[1]) 286 selected = "" 287 288 if type(field_obj).__name__ in "ForeignKey": 289 for choice_item in field_obj.get_choices()[1:]: 290 if admin_obj.filter_condtions.get(filter_column)== str(choice_item[0]): # 就是选择的这个条件,整数转字符串 291 selected = "selected" 292 select_ele += """<option value="%s" %s>%s</option> """ % (choice_item[0], selected, choice_item[1]) 293 selected='' 294 295 if type(field_obj).__name__ in ['DateTimeField', 'DateField']: # 如果是时间格式 296 date_els = [] # 日期条件项 297 today_ele = datetime.now().date() # 今天日期 298 date_els.append(['今天', today_ele]) # 今天 299 date_els.append(['昨天', today_ele - timedelta(days=1)]) # 昨天 300 date_els.append(['近7天', today_ele - timedelta(days=7)]) # 一周 301 date_els.append(['近30天', today_ele - timedelta(days=30)]) # 三十 302 date_els.append(['本月', today_ele.replace(day=1)]) # 本月 303 date_els.append(['近90天', today_ele - timedelta(days=90)]) # 90天 304 date_els.append(['近365天', today_ele - timedelta(days=365)]) # 365天 305 date_els.append(['本年', today_ele.replace(month=1, day=1)]) ##今年 306 307 for choice_item in date_els: 308 if admin_obj.filter_condtions.get("%s__gte" %filter_column)==str(choice_item[1]): 309 selected = 'selected' 310 select_ele += """<option value="%s" %s>%s</option> """ % (choice_item[1], selected, choice_item[0]) 311 selected = '' 312 filter_column_name = "%s__gte" %filter_column 313 else: 314 filter_column_name = filter_column 315 316 select_ele += "</select>" 317 select_ele=select_ele.format(filter_column=filter_column_name)#格式化时间的判断条件 318 return mark_safe(select_ele) 319 # ————————16PerfectCRM实现King_admin日期过滤———————— 320 321 # ————————17PerfectCRM实现King_admin单列排序———————— 322 # kingadmin排序功能 323 @register.simple_tag 324 def get_orderby_key(request,column): 325 current_order_by_key = request.GET.get("_o") 326 # ————————18PerfectCRM实现King_admin搜索关键字———————— 327 search_key = request.GET.get("_q") 328 if search_key != None: 329 if current_order_by_key != None: #如果不为空 #肯定有某列被排序了 330 if current_order_by_key == column: # 判断是否相等 #当前这列正在被排序 331 if column.startswith("-"): #startsWith是String类中的一个方法,用来检测某字符串是否以另一个字符串开始,返回值为boolean类型 332 return column.strip("-") #strip去掉 文本中句子开头与结尾的符号的 333 else: 334 return "-%s&_q=%s" % (column, search_key) 335 return "%s&_q=%s" % (column, search_key) 336 else: 337 # ————————18PerfectCRM实现King_admin搜索关键字———————— 338 if current_order_by_key != None: #如果不为空 #肯定有某列被排序了 339 if current_order_by_key == column: # 判断是否相等 #当前这列正在被排序 340 if column.startswith("-"): #startsWith是String类中的一个方法,用来检测某字符串是否以另一个字符串开始,返回值为boolean类型 341 return column.strip("-") #strip去掉 文本中句子开头与结尾的符号的 342 else: 343 return "-%s"%column 344 # else: 345 # return column 346 # else: 347 # return column 348 return column #同上4句 349 # kingadmin排序功能 350 351 # kingadmin排序功能 显示排序图标 352 # @register.simple_tag 353 # def display_order_by_icon(request, column): 354 # current_order_by_key = request.GET.get("_o") 355 # if current_order_by_key != None: #肯定有某列被排序了 356 # if current_order_by_key.strip("-") == column: ## 当前这列正在被排序 357 # if current_order_by_key.startswith("-"): 358 # icon = "fa-arrow-up" 359 # else: 360 # icon = "fa-arrow-down" 361 # ele = """<i class="fa %s" aria-hidden="true"></i>""" % icon 362 # return mark_safe(ele) 363 # return '' 364 # kingadmin排序功能 显示排序图标 365 @register.simple_tag 366 def display_order_by_icon(request, column): 367 current_order_by_key = request.GET.get("_o") 368 if current_order_by_key != None: #肯定有某列被排序了 369 if current_order_by_key.strip("-") == column: # 当前这列正在被排序 #strip去掉 文本中句子开头与结尾的符号的 370 if current_order_by_key.startswith("-"): #startsWith是String类中的一个方法,用来检测某字符串是否以另一个字符串开始,返回值为boolean类型 371 icon = "▲" 372 else: 373 icon = "▼" 374 ele = """<i style='color: red'>%s</i>""" % icon 375 return mark_safe(ele) 376 return '' #防止出现 None 377 # kingadmin排序功能 显示排序图标 378 379 # kingadmin排序功能 # 过滤后排序功能 #} 380 @register.simple_tag 381 def get_current_orderby_key(request): #注意生成的URL问题 382 #获取当前正在排序的字段名 #<input type="hidden" name="_o" value="{% get_current_orderby_key request %}"> 383 current_order_by_key = request.GET.get("_o") 384 return current_order_by_key or '' 385 # kingadmin排序功能 # 过滤后排序功能 #} 386 387 # kingadmin排序功能 # 过滤后排序功能 # 排序分页 388 @register.simple_tag 389 def generate_order_by_url (request): 390 current_order_by_key = request.GET.get("_o") 391 if current_order_by_key != None: # 肯定有某列被排序了 392 return "&_o=%s" % current_order_by_key 393 return '' 394 # kingadmin排序功能 # 过滤后排序功能 # 排序分页 395 # ————————17PerfectCRM实现King_admin单列排序———————— 396 397 # ————————18PerfectCRM实现King_admin搜索关键字———————— 398 @register.simple_tag 399 def get_search_key(request): # 搜索框里保留搜索值 400 search_key = request.GET.get("_q") 401 return search_key or '' 402 # ————————18PerfectCRM实现King_admin搜索关键字———————— 403 404 # ————————23PerfectCRM实现King_admin数据删除———————— 405 # <-------------------获取删除映射关系-------------------------------- 406 @register.simple_tag 407 def display_all_related_obj(objs): 408 # 取出对象及所有相关联的数据 409 from django.db.models.query import QuerySet 410 if type(objs) != QuerySet: 411 objs = [objs, ] 412 if objs: 413 model_class = objs[0]._meta.model # 取表对象 414 model_name = objs[0]._meta.model_name # 取表名 415 return mark_safe(recursive_related_objs_lookup(objs)) 416 # <-----------------递归获取映射关系-------------------------------- 417 def recursive_related_objs_lookup(objs, name=None, conn_batch_size=0): 418 name = set() 419 print(name) 420 print('传递过来的objs:', objs) 421 # 开始标签的拼接 422 ul_ele = "<ul style='color: blue'>" 423 for obj in objs: 424 li_ele = '''<li>{0}:{1}</li>'''.format(obj._meta.verbose_name, obj.__str__().strip("<>")) 425 print('str:', obj.__str__(), '类型:', type(obj.__str__())) 426 print('关联的表的自定表名:', li_ele) 427 ul_ele += li_ele 428 print('拼接li_ele:', ul_ele) 429 # 映射关系处理 430 # <---------------------------特殊关联处理----------------------------------- 431 # 多对多关系 432 for m2m_field in obj._meta.local_many_to_many: # local_many_to_many返回列表,many_to_many返回元祖 433 print('--开始循环反射-多对多-关系处理--') 434 sub_ul_ele = "<ul style='color: red'>" 435 m2m_field_obj = getattr(obj, m2m_field.name) # 反射 如果有选项 436 print('反射选项:', m2m_field_obj) 437 438 for m2m_data in m2m_field_obj.select_related(): 439 print('开始循环多对多标签拼接:', m2m_data) 440 441 sub_li_ele = '''<li>{0}:{1}</li>'''.format(m2m_field.verbose_name, m2m_data.__str__().strip("<>")) 442 sub_ul_ele += sub_li_ele 443 sub_ul_ele += '</ul>' 444 ul_ele += sub_ul_ele 445 print('生成完整 多对多 标签..:', ul_ele) 446 # <---------------------------外健关联处理------------------------------------ 447 for related_obj in obj._meta.related_objects: 448 print('--开始-外健关联-处理--') 449 if hasattr(obj, related_obj.get_accessor_name()): 450 print('--判断对象中是否包含反查属性--') 451 accessor_obj = getattr(obj, related_obj.get_accessor_name()) 452 print('获取反查对应的对象: ') 453 if hasattr(accessor_obj, 'select_related'): 454 print('--判断有没有获取数据的方法或属性-- ') 455 target_object = accessor_obj.select_related() 456 print('获取数据的方法或属性: ', target_object) 457 458 if 'ManyToManyRel' in related_obj.__repr__(): 459 print('--开始-外健关联-多对多-处理--.') 460 461 # 生成UL 462 sub_ul_ele = '<ul style="color: green">' 463 for data in target_object: 464 print('开始循环-外健关联-标签拼接...', data) 465 sub_li_ele = '''<li>{0}:{1}</li>'''.format(data._meta.verbose_name, 466 data.__str__().strip("<>")) 467 sub_ul_ele += sub_li_ele 468 sub_ul_ele += '</ul>' 469 ul_ele += sub_ul_ele 470 print('-外健关联-生成完整标签:', ul_ele) 471 # <---------------递归处理------------------- 472 if len(target_object) != conn_batch_size: 473 print('--有下级对象存在,进行-递归-循环--') 474 names = target_object.__str__() 475 print(names, type(names)) 476 if names == name: 477 print('--如果是自己关联自己,就不递归了--') 478 ul_ele += '</ul>' 479 return ul_ele 480 else: 481 print('--防止无限递归+1--') 482 conn_batch_size = conn_batch_size + 1 483 node = recursive_related_objs_lookup(target_object, name=names, 484 conn_batch_size=conn_batch_size) 485 ul_ele += node 486 487 # <---------------由于使用递归,下面的标签样会发生重复,就不需要使用了-------------------- 488 else: 489 print('外健关联 一对一:', accessor_obj) 490 target_object = accessor_obj 491 print("外健关联 一对一:", target_object, '属性:', type(target_object)) 492 493 ul_ele += '</ul>' 494 return ul_ele 495 496 # ————————23PerfectCRM实现King_admin数据删除———————— 497 498 499 # ————————24PerfectCRM实现King_admin自定义操作数据———————— 500 #自定制 actions功能 显示 501 @register.simple_tag 502 def get_admin_actions(admin_obj): 503 #选择功能 504 options = "<option class='form-control' value='-1'>-------</option>"#默认为空 505 actions = admin_obj.default_actions + admin_obj.actions #默认加自定制 506 print('默认加自定制',actions) 507 for action in actions: 508 action_func = getattr(admin_obj,action)#功能方法 #反射 509 if hasattr(action_func,"short_description"):#反射 如有自定义的名称执行函数方法 510 action_name = action_func.short_description#等于自定义的名称 #显示中文 511 else: 512 action_name = action#等于函数名称 513 options += """<option value="{action_func_name}">{action_name}</option> """.format(action_func_name=action, action_name=action_name) 514 return mark_safe(options) 515 # ————————24PerfectCRM实现King_admin自定义操作数据———————— 516 517 518 519 # ————————27PerfectCRM实现King_admin编辑复选框———————— 520 # 复选 框内容待选数据 521 @register.simple_tag 522 def get_m2m_available_objs(admin_obj, field_name): 523 '''返回m2m左侧所有待选数据''' 524 # c= admin_obj.model.tags.rel.model.objects.all() 525 # print('c',c) 526 # m2m_objs= admin_obj.model.tags.rel.model.objects.all() 527 # print('m2m_objs',m2m_objs) 528 m2m_model = getattr(admin_obj.model, field_name).rel # 复选框对象 529 m2m_objs = m2m_model.model.objects.all() # 获取到复选框所有内容 530 return m2m_objs 531 532 533 # 复选 框内容已选中数据 534 @register.simple_tag 535 def get_m2m_chosen_objs(admin_obj, field_name, obj): 536 """ 537 返回已选中的列表 538 :param admin_obj: 539 :param field_name: 540 :param obj: 数据对象 541 :return: 542 """ 543 # print(["--->obj",obj]) 544 if obj.id: 545 return getattr(obj, field_name).all() # 返回所有的内容 546 return [] # 没有数据为返回空 创建新的记录使用 547 # ————————27PerfectCRM实现King_admin编辑复选框————————
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 # ————————33PerfectCRM实现King_admin编辑整张表限制———————— 46 readonly_table=False#默认表单不锁定 47 # ————————33PerfectCRM实现King_admin编辑整张表限制———————— 48 49 # ————————36PerfectCRM实现King_admin密码修改———————— 50 modelform_exclude_fields=[]#排除验证字段 51 # ————————36PerfectCRM实现King_admin密码修改———————— 52 53 # ————————55PerfectCRM实现CRM客户报名状态颜色变化———————— 54 colored_fields = {} 55 # ————————55PerfectCRM实现CRM客户报名状态颜色变化———————— 56 57 58 # ————————24PerfectCRM实现King_admin自定义操作数据———————— 59 actions = []#自定功能 60 61 default_actions = ["delete_selected",] #默认删除的函数 62 #默认删除的函数 63 def delete_selected(self,request,queryset): 64 # from django.shortcuts import render, redirect 65 print("goint to delete ",queryset) 66 app_name=self.model._meta.app_label#app名 67 model_name=self.model._meta.model_name#表名 68 objs=queryset#类对象 69 action=request._admin_action 70 print(action,'<-------action') 71 72 # ————————33PerfectCRM实现King_admin编辑整张表限制———————— 73 if self.readonly_table: 74 errors={'锁定的表单':'当前表单已经锁定,不可进行批量删除操作!'} 75 else: 76 errors={} 77 # ————————33PerfectCRM实现King_admin编辑整张表限制———————— 78 79 if request.POST.get('delete_confirm')=='yes': #{#table_delete.html#} 80 81 # ————————33PerfectCRM实现King_admin编辑整张表限制———————— 82 if not self.readonly_table: 83 # ————————33PerfectCRM实现King_admin编辑整张表限制———————— 84 queryset.delete() 85 return redirect('/king_admin/%s/%s/'%(app_name,model_name)) 86 else: 87 return redirect('/king_admin/%s/%s/' % (app_name, model_name)) 88 selected_ids=','.join([str(i.id) for i in queryset]) 89 print(selected_ids,'<---selected_ids') 90 objs=queryset 91 return render(request,"king_admin/table_delete.html", locals()) #返回删除页 92 delete_selected.short_description = "默认批量删除" 93 # ————————24PerfectCRM实现King_admin自定义操作数据———————— 94 95 # ————————28PerfectCRM实现King_admin编辑限制———————— 96 readonly_fields = [] # 不可修改 97 98 # ————————29PerfectCRM实现King_admin编辑自定义限制———————— 99 #默认表单验证 全部 可重写 100 def default_form_validation(self,request): 101 #用户可以在此进行自定义的表单验证,相当于django form 的clean方法 102 '''默认表单验证 == django form 的clean方法''' 103 pass 104 # ————————29PerfectCRM实现King_admin编辑自定义限制———————— 105 # ————————28PerfectCRM实现King_admin编辑限制———————— 106 107 108 # ————————05PerfectCRM实现King_admin注册功能获取内存———————— 109 class AdminSite(object): 110 def __init__(self): 111 self.registered_sites = {} #传到views 里调用 112 def register(self,model,admin_class=None): #默认值None 使用 BaseAdmin 113 app_name = model._meta.app_label#用内置方法获取 APP名字 (crm) 114 model_name = model._meta.model_name#用内置方法获取 表名 (Customer) 115 if app_name not in self.registered_sites: 116 self.registered_sites[app_name] = {} #创建 crm={} 117 if model_name in self.registered_sites[app_name]: 118 raise AdminRegisterException("app [%s] model [%s] has already registered!异常" 119 %(app_name,model_name))#自定义异常, 120 if not admin_class: 121 admin_class = BaseAdmin #默认值None 使用 BaseAdmin 122 # self.registered_sites[app_name][model_name] = admin_class #注册APP 123 # site = AdminSite() # 实例化类 单例模式 124 125 126 # ————————05PerfectCRM实现King_admin注册功能获取内存———————— 127 #registered_sites {'crm': {'customer': <class 'crm.kingadmin.CustomerAdmin'>, 'courserecord': <class 'kingadmin.base_admin.BaseAdmin'>}} 128 #把类名放到class的对象里,然后通过class的对象传到前端 129 # admin_class.model = model 130 # self.registered_sites[app_name][model_name] = admin_class #注册APP 131 # 132 # site = AdminSite() #实例化类 单例模式 133 # ————————05PerfectCRM实现King_admin注册功能获取内存———————— 134 135 # ————————06PerfectCRM实现King_admin注册功能获取内存优化处理———————— 136 #没有实例化会使用同一个内存地址 137 admin_obj = admin_class() #先实例化 138 admin_obj.model = model #参数赋值给实例 139 self.registered_sites[app_name][model_name] = admin_obj#注册APP 140 #实例化后,调用会使用不同的内存地址 141 142 site = AdminSite() #实例化类 单例模式 143 # ————————06PerfectCRM实现King_admin注册功能获取内存优化处理———————— 144 145 # registered_sites={} 146 # def register(model,admin_class=None): #默认值None 使用 BaseAdmin 147 # app_name = model._meta.app_label#用内置方法获取 APP名字 (crm) 148 # model_name = model._meta.model_name#用内置方法获取 表名 (Customer) 149 # if app_name not in registered_sites: 150 # registered_sites[app_name] = {} #创建 crm={} 151 # if model_name in registered_sites[app_name]: 152 # raise AdminRegisterException("app [%s] model [%s] has already registered!异常" 153 # %(app_name,model_name))#自定义异常 154 # if not admin_class: 155 # admin_class = BaseAdmin #默认值None 使用class BaseAdmin 156 # registered_sites[app_name][model_name] = admin_class #注册APP 157 158 # ————————05PerfectCRM实现King_admin注册功能获取内存———————— 159 160 # ————————04PerfectCRM实现King_admin注册功能————————
您的资助是我最大的动力!
金额随意,欢迎来赏!
如果,您希望更容易地发现我的新博客,不妨点击一下绿色通道的
因为,我的写作热情也离不开您的肯定支持,感谢您的阅读,我是【颜言】!