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