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 # ————————56PerfectCRM实现CRM客户首列进入更改页优化路径————————
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 # ————————56PerfectCRM实现CRM客户首列进入更改页优化路径————————
149 # ————————56PerfectCRM实现CRM客户首列进入更改页优化路径————————
150 elif index == 0:#首列可点击进入更改页
151 td_ele = '''<td><a class='btn-link' href='%s%s/change/'>%s</a> </td> ''' %(request.path, obj.id,column_data)
152 # ————————56PerfectCRM实现CRM客户首列进入更改页优化路径————————
153
154
155 # ————————55PerfectCRM实现CRM客户报名状态颜色变化————————
156 elif column in admin_obj.colored_fields: #特定字段需要显示颜色 #如果admin_obj有配置colored_fields
157 color_dic = admin_obj.colored_fields[column] #获取配置#字段名# 'status':{'已报名':"rgba(145, 255, 0, 0.78)",
158 if column_data in color_dic: #如果#已报名#有在配置里
159 td_ele = "<td style='background-color:%s'>%s</td>" % (color_dic[column_data],column_data) #颜色#已报名
160 else:
161 td_ele = "<td>%s</td>" % column_data
162 # ————————55PerfectCRM实现CRM客户报名状态颜色变化————————
163
164 else:
165 td_ele = '''<td>%s</td>''' % column_data
166 # td_ele = '''<td>%s</td>''' % column_data #把反射来的值 拼接字符串 生成<td>
167 # ————————19PerfectCRM实现King_admin数据修改————————
168 # ————————54PerfectCRM实现CRM客户报名链接————————
169 # admin_obj.column_not = False #表示是表中字段
170 except FieldDoesNotExist as e: # 如果没有获取到
171 if hasattr(admin_obj, column): # 从自定义的函数中取值
172 column_func = getattr(admin_obj, column)
173 admin_obj.instance = obj # 对象加入
174
175 column_not.append(column) # 加入非表中字段列表,
176 admin_obj.column_not = column_not # 对象加入
177 column_data = column_func()
178 print('column_data', column_data)
179 td_ele = '''<td>%s</td>''' % column_data
180 # ————————54PerfectCRM实现CRM客户报名链接————————
181 row_ele += td_ele #把 <td> 拼接到上面到空字符串
182 else:
183 row_ele +="<td>%s</td>" %obj #把<td>拼接到上面到空字符串,crm/models.py里 def __str__(self):的返回值
184 return mark_safe(row_ele) #使用mark_safe函数标记后,django将不再对该函数的内容进行转义
185 # ————————54PerfectCRM实现CRM客户报名链接————————
186 # ————————54PerfectCRM实现CRM客户报名链接————————
187 ##表中自定verbose_name列名
188 @register.simple_tag
189 def verbose_name_set(admin_obj,column):
190 try:
191 verbose_name=admin_obj.model._meta.get_field(column).verbose_name.upper()#获取别名
192 print(verbose_name,'verbose_name_set')
193 print(admin_obj.model._meta,'all')
194 except FieldDoesNotExist as e:
195 verbose_name=getattr(admin_obj,column).display_name.upper()
196 return verbose_name
197 # ————————54PerfectCRM实现CRM客户报名链接————————
198
199
200
201 # ————————13PerfectCRM实现King_admin分页页数————————
202 #分页功能kingadmin/templates/kingadmin/table_data_list.html里 <a href="?page={{ page }}{% generate_filter_url admin_obj %}">{{ page }}
203 @register.simple_tag
204 def generate_filter_url(admin_obj): #拼接URL
205 url = ''
206 for k,v in admin_obj.filter_condtions.items():
207 url += "&%s=%s" %(k,v )
208 return url
209 # ————————13PerfectCRM实现King_admin分页页数————————
210
211 # ————————14PerfectCRM实现King_admin分页的省略显示————————
212 #分页的省略显示
213 @register.simple_tag
214 def pag_omit(request,admin_obj):#传入当前页面值
215 rest=''#大字符串
216 # ————————18PerfectCRM实现King_admin搜索关键字————————
217 search_key = get_search_key(request) # 搜索
218 # ————————18PerfectCRM实现King_admin搜索关键字————————
219 # ————————17PerfectCRM实现King_admin单列排序————————
220 order_by_url = generate_order_by_url(request) # 排序
221 # ————————17PerfectCRM实现King_admin单列排序————————
222 # ————————15PerfectCRM实现King_admin多条件过滤————————
223 filters = generate_filter_url(admin_obj) # 分页
224 # ————————15PerfectCRM实现King_admin多条件过滤————————
225 add_tags=False#标志位
226 for pages in admin_obj.querysets.paginator.page_range:
227 # 前两页 或 后 两页 或 当前页的前后页
228 if pages < 3 or pages>admin_obj.querysets.paginator.num_pages -2 or abs(admin_obj.querysets.number -pages) <=2:
229 #样式
230 add_tags=False
231 ele_class='' #颜色
232 if pages == admin_obj.querysets.number: #--如果是当前页码,颜色加深 不进链接跳转--
233 ele_class="active" #颜色加深
234 # ————————18PerfectCRM实现King_admin搜索关键字————————
235 # ————————17PerfectCRM实现King_admin单列排序————————
236 # ————————15PerfectCRM实现King_admin多条件过滤————————
237 # rest+='''<li class="%s"><a href="?page=%s">%s</a></li>'''%(ele_class,pages,pages) #--拼接URL--
238 # rest+='''<li class="%s"><a href="?page=%s%s">%s</a></li>'''%(ele_class,pages,filters,pages) #--拼接URL--
239 # ————————15PerfectCRM实现King_admin多条件过滤————————
240 # rest+='''<li class="%s"><a href="?page=%s%s%s">%s<span class="sr-only">(current)</span></a></li>'''\
241 # %(ele_class,pages,order_by_url,filters,pages)
242 # ————————17PerfectCRM实现King_admin单列排序————————
243 rest+='''<li class="%s"><a href="?page=%s%s%s&_q=%s">%s<span class="sr-only">(current)</span></a></li>'''\
244 %(ele_class,pages,order_by_url,filters,search_key,pages)
245 # ————————18PerfectCRM实现King_admin搜索关键字————————
246 else:#其他的用省略号表示
247 if add_tags==False:#如果不是标志位的页面
248 rest+='<li><a>...</a></li>'
249 add_tags=True#标志位为真
250 return mark_safe(rest) #使用mark_safe函数标记后,django将不再对该函数的内容进行转义
251
252 # ————————14PerfectCRM实现King_admin分页的省略显示————————
253
254
255
256 # # ————————15PerfectCRM实现King_admin多条件过滤————————
257 # #多条件过滤 table_data_list.html 传递参数
258 # @register.simple_tag
259 # def get_filter_field (filter_column,admin_obj):
260 # print("admin obj",admin_obj.model ,filter_column)
261 # field_obj = admin_obj.model._meta.get_field(filter_column)#调用内置方法
262 # select_ele = """<select name="%s"> """ %filter_column #拼接成下拉框返回
263 # for choice in field_obj.get_choices():#循环获取crm/models里class Customer(models.Model):下source_choices = ((0,'转介绍'),
264 # selected_condtion = admin_obj.filter_condtions.get(filter_column)
265 # if selected_condtion != None: #if None, 没有过滤这个条件
266 # print("heoe....",filter_column,selected_condtion,type(selected_condtion))#类型是 整数
267 # if selected_condtion == str(choice[0]): #就是选择的这个条件,整数转字符串
268 # selected = "selected"
269 # else:
270 # selected = ""
271 # else:
272 # selected = ""
273 #
274 # #在前端把几个条件提交到后台,后台拿着条件变成一个字典,然后进行过滤,把数据返回前端,并且把条件作为字典返回后端,因为要在前端显示已经过滤的条件。
275 # option_ele = """<option value="%s" %s>%s</option> """ % (choice[0],selected,choice[1])
276 # select_ele +=option_ele
277 # select_ele += "</select>"
278 # return mark_safe(select_ele)
279 # # ————————15PerfectCRM实现King_admin多条件过滤————————
280
281 # # ————————16PerfectCRM实现King_admin日期过滤————————
282 from django.utils.timezone import datetime,timedelta
283 @register.simple_tag
284 def get_filter_field (filter_column,admin_obj):
285 select_ele = """<select name='{filter_column}'><option value="">---------</option>""" #标签 字符串 #拼接成下拉框返回
286 field_obj = admin_obj.model._meta.get_field(filter_column)#调用内置方法
287 selected = ''
288 if field_obj.choices:
289 for choice_item in field_obj.choices:
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 "ForeignKey":
296 for choice_item in field_obj.get_choices()[1:]:
297 if admin_obj.filter_condtions.get(filter_column)== str(choice_item[0]): # 就是选择的这个条件,整数转字符串
298 selected = "selected"
299 select_ele += """<option value="%s" %s>%s</option> """ % (choice_item[0], selected, choice_item[1])
300 selected=''
301
302 if type(field_obj).__name__ in ['DateTimeField', 'DateField']: # 如果是时间格式
303 date_els = [] # 日期条件项
304 today_ele = datetime.now().date() # 今天日期
305 date_els.append(['今天', today_ele]) # 今天
306 date_els.append(['昨天', today_ele - timedelta(days=1)]) # 昨天
307 date_els.append(['近7天', today_ele - timedelta(days=7)]) # 一周
308 date_els.append(['近30天', today_ele - timedelta(days=30)]) # 三十
309 date_els.append(['本月', today_ele.replace(day=1)]) # 本月
310 date_els.append(['近90天', today_ele - timedelta(days=90)]) # 90天
311 date_els.append(['近365天', today_ele - timedelta(days=365)]) # 365天
312 date_els.append(['本年', today_ele.replace(month=1, day=1)]) ##今年
313
314 for choice_item in date_els:
315 if admin_obj.filter_condtions.get("%s__gte" %filter_column)==str(choice_item[1]):
316 selected = 'selected'
317 select_ele += """<option value="%s" %s>%s</option> """ % (choice_item[1], selected, choice_item[0])
318 selected = ''
319 filter_column_name = "%s__gte" %filter_column
320 else:
321 filter_column_name = filter_column
322
323 select_ele += "</select>"
324 select_ele=select_ele.format(filter_column=filter_column_name)#格式化时间的判断条件
325 return mark_safe(select_ele)
326 # ————————16PerfectCRM实现King_admin日期过滤————————
327
328 # ————————17PerfectCRM实现King_admin单列排序————————
329 # kingadmin排序功能
330 @register.simple_tag
331 def get_orderby_key(request,column):
332 current_order_by_key = request.GET.get("_o")
333 # ————————18PerfectCRM实现King_admin搜索关键字————————
334 search_key = request.GET.get("_q")
335 if search_key != None:
336 if current_order_by_key != None: #如果不为空 #肯定有某列被排序了
337 if current_order_by_key == column: # 判断是否相等 #当前这列正在被排序
338 if column.startswith("-"): #startsWith是String类中的一个方法,用来检测某字符串是否以另一个字符串开始,返回值为boolean类型
339 return column.strip("-") #strip去掉 文本中句子开头与结尾的符号的
340 else:
341 return "-%s&_q=%s" % (column, search_key)
342 return "%s&_q=%s" % (column, search_key)
343 else:
344 # ————————18PerfectCRM实现King_admin搜索关键字————————
345 if current_order_by_key != None: #如果不为空 #肯定有某列被排序了
346 if current_order_by_key == column: # 判断是否相等 #当前这列正在被排序
347 if column.startswith("-"): #startsWith是String类中的一个方法,用来检测某字符串是否以另一个字符串开始,返回值为boolean类型
348 return column.strip("-") #strip去掉 文本中句子开头与结尾的符号的
349 else:
350 return "-%s"%column
351 # else:
352 # return column
353 # else:
354 # return column
355 return column #同上4句
356 # kingadmin排序功能
357
358 # kingadmin排序功能 显示排序图标
359 # @register.simple_tag
360 # def display_order_by_icon(request, column):
361 # current_order_by_key = request.GET.get("_o")
362 # if current_order_by_key != None: #肯定有某列被排序了
363 # if current_order_by_key.strip("-") == column: ## 当前这列正在被排序
364 # if current_order_by_key.startswith("-"):
365 # icon = "fa-arrow-up"
366 # else:
367 # icon = "fa-arrow-down"
368 # ele = """<i class="fa %s" aria-hidden="true"></i>""" % icon
369 # return mark_safe(ele)
370 # return ''
371 # kingadmin排序功能 显示排序图标
372 @register.simple_tag
373 def display_order_by_icon(request, column):
374 current_order_by_key = request.GET.get("_o")
375 if current_order_by_key != None: #肯定有某列被排序了
376 if current_order_by_key.strip("-") == column: # 当前这列正在被排序 #strip去掉 文本中句子开头与结尾的符号的
377 if current_order_by_key.startswith("-"): #startsWith是String类中的一个方法,用来检测某字符串是否以另一个字符串开始,返回值为boolean类型
378 icon = "▲"
379 else:
380 icon = "▼"
381 ele = """<i style='color: red'>%s</i>""" % icon
382 return mark_safe(ele)
383 return '' #防止出现 None
384 # kingadmin排序功能 显示排序图标
385
386 # kingadmin排序功能 # 过滤后排序功能 #}
387 @register.simple_tag
388 def get_current_orderby_key(request): #注意生成的URL问题
389 #获取当前正在排序的字段名 #<input type="hidden" name="_o" value="{% get_current_orderby_key request %}">
390 current_order_by_key = request.GET.get("_o")
391 return current_order_by_key or ''
392 # kingadmin排序功能 # 过滤后排序功能 #}
393
394 # kingadmin排序功能 # 过滤后排序功能 # 排序分页
395 @register.simple_tag
396 def generate_order_by_url (request):
397 current_order_by_key = request.GET.get("_o")
398 if current_order_by_key != None: # 肯定有某列被排序了
399 return "&_o=%s" % current_order_by_key
400 return ''
401 # kingadmin排序功能 # 过滤后排序功能 # 排序分页
402 # ————————17PerfectCRM实现King_admin单列排序————————
403
404 # ————————18PerfectCRM实现King_admin搜索关键字————————
405 @register.simple_tag
406 def get_search_key(request): # 搜索框里保留搜索值
407 search_key = request.GET.get("_q")
408 return search_key or ''
409 # ————————18PerfectCRM实现King_admin搜索关键字————————
410
411 # ————————23PerfectCRM实现King_admin数据删除————————
412 # <-------------------获取删除映射关系--------------------------------
413 @register.simple_tag
414 def display_all_related_obj(objs):
415 # 取出对象及所有相关联的数据
416 from django.db.models.query import QuerySet
417 if type(objs) != QuerySet:
418 objs = [objs, ]
419 if objs:
420 model_class = objs[0]._meta.model # 取表对象
421 model_name = objs[0]._meta.model_name # 取表名
422 return mark_safe(recursive_related_objs_lookup(objs))
423 # <-----------------递归获取映射关系--------------------------------
424 def recursive_related_objs_lookup(objs, name=None, conn_batch_size=0):
425 name = set()
426 print(name)
427 print('传递过来的objs:', objs)
428 # 开始标签的拼接
429 ul_ele = "<ul style='color: blue'>"
430 for obj in objs:
431 li_ele = '''<li>{0}:{1}</li>'''.format(obj._meta.verbose_name, obj.__str__().strip("<>"))
432 print('str:', obj.__str__(), '类型:', type(obj.__str__()))
433 print('关联的表的自定表名:', li_ele)
434 ul_ele += li_ele
435 print('拼接li_ele:', ul_ele)
436 # 映射关系处理
437 # <---------------------------特殊关联处理-----------------------------------
438 # 多对多关系
439 for m2m_field in obj._meta.local_many_to_many: # local_many_to_many返回列表,many_to_many返回元祖
440 print('--开始循环反射-多对多-关系处理--')
441 sub_ul_ele = "<ul style='color: red'>"
442 m2m_field_obj = getattr(obj, m2m_field.name) # 反射 如果有选项
443 print('反射选项:', m2m_field_obj)
444
445 for m2m_data in m2m_field_obj.select_related():
446 print('开始循环多对多标签拼接:', m2m_data)
447
448 sub_li_ele = '''<li>{0}:{1}</li>'''.format(m2m_field.verbose_name, m2m_data.__str__().strip("<>"))
449 sub_ul_ele += sub_li_ele
450 sub_ul_ele += '</ul>'
451 ul_ele += sub_ul_ele
452 print('生成完整 多对多 标签..:', ul_ele)
453 # <---------------------------外健关联处理------------------------------------
454 for related_obj in obj._meta.related_objects:
455 print('--开始-外健关联-处理--')
456 if hasattr(obj, related_obj.get_accessor_name()):
457 print('--判断对象中是否包含反查属性--')
458 accessor_obj = getattr(obj, related_obj.get_accessor_name())
459 print('获取反查对应的对象: ')
460 if hasattr(accessor_obj, 'select_related'):
461 print('--判断有没有获取数据的方法或属性-- ')
462 target_object = accessor_obj.select_related()
463 print('获取数据的方法或属性: ', target_object)
464
465 if 'ManyToManyRel' in related_obj.__repr__():
466 print('--开始-外健关联-多对多-处理--.')
467
468 # 生成UL
469 sub_ul_ele = '<ul style="color: green">'
470 for data in target_object:
471 print('开始循环-外健关联-标签拼接...', data)
472 sub_li_ele = '''<li>{0}:{1}</li>'''.format(data._meta.verbose_name,
473 data.__str__().strip("<>"))
474 sub_ul_ele += sub_li_ele
475 sub_ul_ele += '</ul>'
476 ul_ele += sub_ul_ele
477 print('-外健关联-生成完整标签:', ul_ele)
478 # <---------------递归处理-------------------
479 if len(target_object) != conn_batch_size:
480 print('--有下级对象存在,进行-递归-循环--')
481 names = target_object.__str__()
482 print(names, type(names))
483 if names == name:
484 print('--如果是自己关联自己,就不递归了--')
485 ul_ele += '</ul>'
486 return ul_ele
487 else:
488 print('--防止无限递归+1--')
489 conn_batch_size = conn_batch_size + 1
490 node = recursive_related_objs_lookup(target_object, name=names,
491 conn_batch_size=conn_batch_size)
492 ul_ele += node
493
494 # <---------------由于使用递归,下面的标签样会发生重复,就不需要使用了--------------------
495 else:
496 print('外健关联 一对一:', accessor_obj)
497 target_object = accessor_obj
498 print("外健关联 一对一:", target_object, '属性:', type(target_object))
499
500 ul_ele += '</ul>'
501 return ul_ele
502
503 # ————————23PerfectCRM实现King_admin数据删除————————
504
505
506 # ————————24PerfectCRM实现King_admin自定义操作数据————————
507 #自定制 actions功能 显示
508 @register.simple_tag
509 def get_admin_actions(admin_obj):
510 #选择功能
511 options = "<option class='form-control' value='-1'>-------</option>"#默认为空
512 actions = admin_obj.default_actions + admin_obj.actions #默认加自定制
513 print('默认加自定制',actions)
514 for action in actions:
515 action_func = getattr(admin_obj,action)#功能方法 #反射
516 if hasattr(action_func,"short_description"):#反射 如有自定义的名称执行函数方法
517 action_name = action_func.short_description#等于自定义的名称 #显示中文
518 else:
519 action_name = action#等于函数名称
520 options += """<option value="{action_func_name}">{action_name}</option> """.format(action_func_name=action, action_name=action_name)
521 return mark_safe(options)
522 # ————————24PerfectCRM实现King_admin自定义操作数据————————
523
524
525
526 # ————————27PerfectCRM实现King_admin编辑复选框————————
527 # 复选 框内容待选数据
528 @register.simple_tag
529 def get_m2m_available_objs(admin_obj, field_name):
530 '''返回m2m左侧所有待选数据'''
531 # c= admin_obj.model.tags.rel.model.objects.all()
532 # print('c',c)
533 # m2m_objs= admin_obj.model.tags.rel.model.objects.all()
534 # print('m2m_objs',m2m_objs)
535 m2m_model = getattr(admin_obj.model, field_name).rel # 复选框对象
536 m2m_objs = m2m_model.model.objects.all() # 获取到复选框所有内容
537 return m2m_objs
538
539
540 # 复选 框内容已选中数据
541 @register.simple_tag
542 def get_m2m_chosen_objs(admin_obj, field_name, obj):
543 """
544 返回已选中的列表
545 :param admin_obj:
546 :param field_name:
547 :param obj: 数据对象
548 :return:
549 """
550 # print(["--->obj",obj])
551 if obj.id:
552 return getattr(obj, field_name).all() # 返回所有的内容
553 return [] # 没有数据为返回空 创建新的记录使用
554 # ————————27PerfectCRM实现King_admin编辑复选框————————