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. # ————————24PerfectCRM实现King_admin自定义操作数据————————
  64. # from django.shortcuts import render
  65. actions = ['test_actions',]#定制功能 #测试返回到一个新页面
  66. def test_actions(self,request,arg2):#对应的函数 #request类自己的请求 #arg2类的内容
  67. return render(request,"king_admin/table_index.html")
  68. test_actions.short_description = "测试显示中文"
  69. # ————————24PerfectCRM实现King_admin自定义操作数据————————
  70.  
  71. # ————————28PerfectCRM实现King_admin编辑限制————————
  72. # ————————31PerfectCRM实现King_admin编辑多对多限制————————
  73. # readonly_fields = ('qq', 'consultant',) # 不可修改
  74. readonly_fields = ('qq', 'consultant','tags',) # 不可修改
  75. # ————————31PerfectCRM实现King_admin编辑多对多限制————————
  76.  
  77. # ————————29PerfectCRM实现King_admin编辑自定义限制————————
  78. def default_form_validation(self,obj):
  79. print('validation:制定的',obj.cleaned_data)
  80. consult_course=obj.cleaned_data.get('content','')#自制验证字段
  81. if len(consult_course)<10:
  82. return ValidationError(#添加错误信息 返回
  83. ("该字段%(field)s 咨询内容记录不能少于10个字符"),
  84. code='invalid',
  85. params={'field':'content',},
  86. )
  87. # ————————29PerfectCRM实现King_admin编辑自定义限制————————
  88.  
  89. # ————————28PerfectCRM实现King_admin编辑限制————————
  90.  
  91. # ————————30PerfectCRM实现King_admin编辑自定义字段验证————————
  92. def clean_name(self,obj,*args,**kwargs):#名称验证 单个
  93. name=obj.cleaned_data['name']
  94. if not name:
  95. obj.add_error('name','不能为空!')
  96. return ValidationError(#添加错误信息 返回
  97. ("%(field)s:该字段 不能为空"),
  98. code='invalid',
  99. params={'field':'name',},
  100. )
  101. elif len(name)<5:
  102. obj.add_error('name','不能小于5个字符!')
  103. #return ValidationError('',)
  104. return ValidationError(#添加错误信息 返回
  105. ("%(field)s:该字段 不能小于5个字符!"),
  106. code='invalid',
  107. params={'field':'name',},
  108. )
  109. # ————————30PerfectCRM实现King_admin编辑自定义字段验证————————
  110.  
  111. # ————————34PerfectCRM实现CRM自定义用户————————
  112. #10账号表
  113. class UserProfileAdmin(BaseAdmin):#定制Djanago admin
  114. list_display = ('id', 'email', 'name') # 显示字段表头
  115.  
  116. # ————————36PerfectCRM实现King_admin密码修改————————
  117. readonly_fields = ('password',) # 不可修改,限制
  118. filter_horizontal = ('user_permissions','groups') #复选框
  119. modelform_exclude_fields=['last_login']#排除#不显示 #自增日期 #base_admin.py #forms.py
  120. # ————————36PerfectCRM实现King_admin密码修改————————
  121.  
  122. site.register(models.UserProfile, UserProfileAdmin)
  123. # ————————34PerfectCRM实现CRM自定义用户————————
  124.  
  125. # ————————05PerfectCRM实现King_admin注册功能获取内存————————
  126. # register(models.Customer,CustomerAdmin)
  127. # register(models.CourseRecord)
  128. site.register(models.Customer,CustomerAdmin)
  129. site.register(models.CourseRecord)
  130. # ————————05PerfectCRM实现King_admin注册功能获取内存————————
  131.  
  132. # ————————04PerfectCRM实现King_admin注册功能————————

# kingadmin.py

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

#kingadmin_tags.py

  1. {#table_data_list.html#}
  2. {## ————————08PerfectCRM实现King_admin显示注册表的字段表头————————#}
  3.  
  4. {% extends 'king_master/king_index.html' %} {#继承模板#}
  5. {% load kingadmin_tags %} {#通过自己定义标签获取中文,Django中利用filtersimple_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. {## ————————15PerfectCRM实现King_admin多条件过滤————————#}
  35. {#判断 crm/kingadmin.py class CustomerAdmin(BaseAdmin):有没有使用list_filter = ('source',) #}
  36. {% if admin_obj.list_filter %}
  37. <div class="row">
  38. <form>
  39. {#循环 上面 list_filter = ('source',) 的字段 #}
  40. {% for filter_column in admin_obj.list_filter %}
  41. <div class="col-lg-1">{#最多12 空间 #}
  42. <div>{{ filter_column }}</div>
  43.  
  44. {#到后端取值,传参数到后端, kingadmin/templatetags/kingadmin_tags.pydef get_filter_field (filter_column,admin_obj): #}
  45. <div>{% get_filter_field filter_column admin_obj %}</div>
  46. </div>
  47. {% endfor %}
  48. <div>
  49. <input type="submit" class="btn btn-success" value="过滤">
  50. </div>
  51.  
  52. {## ————————17PerfectCRM实现King_admin单列排序————————#}
  53. <div>
  54. {# 隐藏 #} {# 过滤后排序功能 #}
  55. <input type="hidden" name="_o" value="{% get_current_orderby_key request %}">
  56. </div>
  57. {## ————————17PerfectCRM实现King_admin单列排序————————#}
  58.  
  59. {## ————————18PerfectCRM实现King_admin搜索关键字————————#}
  60. <hr> {#过滤后搜索功能1#} {## 搜索框里保留搜索值 #}
  61. {# <input type="text" name="_q" value="{% get_search_key request %}">#}
  62.  
  63. <div class="row">
  64. <div class="col-lg-2">
  65. <input type="text" name="_q" value="{% get_search_key request %}">
  66. </div>
  67. <div class="col-lg-2">
  68. <input type="submit" class="btn btn-success" value="搜索">
  69. </div>
  70.  
  71. <div style='color: red'> 搜索条件包含:
  72. {% for search_field in admin_obj.search_fields %}
  73. {{ search_field }}
  74. +
  75. {% endfor %}
  76. </div>
  77. </div>
  78. {## ————————18PerfectCRM实现King_admin搜索关键字————————#}
  79.  
  80. </form>
  81. </div>
  82. {% endif %}
  83. {## ————————15PerfectCRM实现King_admin多条件过滤————————#}
  84.  
  85. {## ————————24PerfectCRM实现King_admin自定义操作数据————————#}
  86. <hr>
  87. <div class="row">
  88. <form method="post" onsubmit="return ActionValidation(this)">{% csrf_token %}
  89. <div class="col-lg-2">
  90. <select name="action_select">
  91. {% get_admin_actions admin_obj %}
  92. </select>
  93. </div>
  94.  
  95. <div class="col-lg-2">
  96. <input type="submit" class="btn btn-success" value="执行">
  97. </div>
  98. </form>
  99. </div>
  100. {## ————————24PerfectCRM实现King_admin自定义操作数据————————#}
  101.  
  102. <table class="table table-hover">
  103. <thead>
  104.  
  105. <tr>
  106. {## ————————24PerfectCRM实现King_admin自定义操作数据————————#}
  107. <th><input type="checkbox" onclick="SelectAll(this);"></th>
  108. {## ————————24PerfectCRM实现King_admin自定义操作数据————————#}
  109.  
  110. {## ————————17PerfectCRM实现King_admin单列排序————————#}
  111. {#循环调用kingadmin/base_admin里的class BaseAdmin下的list_display = () 方法#}
  112. {# {% for column in admin_obj.list_display %}#}
  113. {# <th>{{ column }}</th>#}
  114. {# {% endfor %}#}
  115. {# #}
  116. {% for column in admin_obj.list_display %}
  117. {# <th>{{ column }}</th>#} {#过滤功能1#}
  118. {#排序功能1#}
  119. <th>
  120. {# <a href="?_o={{ column }}">{{ column }}</a>#} {#http://127.0.0.1:8000/kingadmin/crm/customer/?_o=qq#}
  121. {## kingadmin排序功能#}
  122. {# <a href="?_o={% get_orderby_key request column %}">{{ column }}</a>#}
  123.  
  124. {## ————————54PerfectCRM实现CRM客户报名链接————————#}
  125. {## kingadmin排序功能#} {# 过滤后排序功能 #}
  126. {# <a href="?_o={% get_orderby_key request column %}{% generate_filter_url admin_obj %}">{{ column }}</a>#}
  127. {##}
  128. {#显示排序图标#}
  129. {# {% display_order_by_icon request column %}#}
  130. {## ————————54PerfectCRM实现CRM客户报名链接————————#}
  131. {## ————————54PerfectCRM实现CRM客户报名链接————————#}
  132. <!-- 非表中的字段-->
  133. {% if column in admin_obj.column_not %}
  134. <a>{% verbose_name_set admin_obj column %}</a>
  135. {% else %}
  136. <a href="?_o={% get_orderby_key request column %}{% generate_filter_url admin_obj %}">{% verbose_name_set admin_obj column %}</a>
  137. {% display_order_by_icon request column %}
  138. {% endif %}
  139. {## ————————54PerfectCRM实现CRM客户报名链接————————#}
  140. </th>
  141. {#排序功能1#}
  142. {% endfor %}
  143. {## ————————17PerfectCRM实现King_admin单列排序————————#}
  144.  
  145. </tr>
  146. </thead>
  147.  
  148. {## ————————09PerfectCRM实现King_admin显示注册表的内容————————#}
  149. <tbody>
  150. {#循环调用kingadmin/views 里的def table_data_list下的admin_obj.querysets #}
  151. {% for obj in admin_obj.querysets %}
  152. <tr>
  153. {## ————————24PerfectCRM实现King_admin自定义操作数据————————#}
  154. <td><input tag="obj_checkbox" type="checkbox" value="{{ obj.id }}"> </td>
  155. {## ————————24PerfectCRM实现King_admin自定义操作数据————————#}
  156.  
  157. {#通过kingadmin_tags在后台处理 再传到前端 #}
  158. {#调用kingadmin/templateags/kingadmin_tags 里的def build_table_row(admin_obj,obj):#}
  159. {## ————————19PerfectCRM实现King_admin数据修改————————#}
  160. {% build_table_row admin_obj obj %}{# kingadmin动态生成model编辑 #}
  161. {## ————————19PerfectCRM实现King_admin数据修改————————#}
  162.  
  163. </tr>
  164. {% endfor %}
  165. </tbody>
  166. {## ————————09PerfectCRM实现King_admin显示注册表的内容————————#}
  167. </table>
  168.  
  169. {## ————————24PerfectCRM实现King_admin自定义操作数据————————#}
  170. <div class="radio">
  171. 数据总量: {{ admin_obj.querysets.paginator.count }}
  172. </div>
  173. {## ————————24PerfectCRM实现King_admin自定义操作数据————————#}
  174.  
  175. {## ————————12PerfectCRM实现King_admin分页上下页————————#}
  176. {# <div class="row">#}
  177. {# <div class="pagination">#}
  178. {# <span class="step-links">#}
  179. {# {% if admin_obj.querysets.has_previous %}#}
  180. {##}
  181. {## ————————15PerfectCRM实现King_admin多条件过滤————————#}
  182. {# <a href="?page={{ admin_obj.querysets.previous_page_number }}#}
  183. {# <a href="?page={{ admin_obj.querysets.previous_page_number }}{% generate_filter_url admin_obj %}">上一页 </a>#}
  184. {## ————————15PerfectCRM实现King_admin多条件过滤————————#}
  185. {##}
  186. {# {% endif %}#}
  187. {##}
  188. {# <span class="current">#}
  189. {# 第{{ admin_obj.querysets.number }}页,共{{ admin_obj.querysets.paginator.num_pages }}页#}
  190. {# </span>#}
  191. {##}
  192. {# {% if admin_obj.querysets.has_next %}#}
  193. {##}
  194. {## ————————15PerfectCRM实现King_admin多条件过滤————————#}
  195. {# <a href="?page={{ admin_obj.querysets.next_page_number }}#}
  196. {# <a href="?page={{ admin_obj.querysets.next_page_number }}{% generate_filter_url admin_obj %}">下一页</a>#}
  197. {## ————————15PerfectCRM实现King_admin多条件过滤————————#}
  198. {##}
  199. {# {% endif %}#}
  200. {# </span>#}
  201. {# </div>#}
  202. {# </div>#}
  203. {## ————————12PerfectCRM实现King_admin分页上下页————————#}
  204.  
  205. {## ————————13PerfectCRM实现King_admin分页页数————————#}
  206. {# <nav aria-label="...">#}
  207. {# <ul class="pagination">#}
  208. {# <li class="disabled"></li>#}
  209. {# {% for page in admin_obj.querysets.paginator.page_range %} {#循环 分页 范围#}
  210. {##}
  211. {# {% if page == admin_obj.querysets.number %} {#当前页高亮,否则不加高亮#}
  212. {# <li class="active">#}
  213. {# {% else %}#}
  214. {# <li >#}
  215. {# {% endif %}#}
  216. {##}
  217. {#后台拼接返回,kingadmin/templatetags/kingadmin_tags.py def generate_filter_url(admin_obj):#}
  218. {# <a href="?page={{ page }}{% generate_filter_url admin_obj %}">{{ page }}</a>#}
  219. {# </li>#}
  220. {# {% endfor %}#}
  221. {# </ul>#}
  222. {# </nav>#}
  223. {## ————————13PerfectCRM实现King_admin分页页数————————#}
  224.  
  225. {## ————————14PerfectCRM实现King_admin分页的省略显示————————#}
  226.  
  227. <div class="row panel-body">
  228. <nav aria-label="...">
  229. <ul class="pagination">
  230. <!--如果有上一页-->
  231. {% if admin_obj.querysets.has_previous %}
  232. {## ————————18PerfectCRM实现King_admin搜索关键字————————#}
  233. {## ————————17PerfectCRM实现King_admin单列排序————————#}
  234. {# <li><a href="?page={{ admin_obj.querysets.previous_page_number }}{% generate_filter_url admin_obj %}"#}
  235. {# aria-label="Previous"><span aria-hidden="true">&laquo;</span></a></li>#}
  236.  
  237. {#获取上一个数字#} {# kingadmin排序功能 # 过滤后排序功能#排序#} {#分页#}
  238. {#<li><a href="?page={{ admin_obj.querysets.previous_page_number }}{% generate_order_by_url request %}{% generate_filter_url admin_obj %}"#}
  239. {# aria-label="Previous"><span aria-hidden="true">上页</span></a></li>#}
  240. {## ————————17PerfectCRM实现King_admin单列排序————————#}
  241. <li><a href="?page={{ admin_obj.querysets.previous_page_number }}
  242. {% generate_order_by_url request %}{% generate_filter_url admin_obj %}&_q={% get_search_key request %}"
  243. aria-label="Previous"><span aria-hidden="true">上页</span></a></li>
  244. {## ————————18PerfectCRM实现King_admin搜索关键字————————#}
  245. {% else %}
  246. <li class="disabled">
  247. <a href="#" aria-label="Previous"><span aria-hidden="true">&laquo;</span></a></li>
  248. {% endif %}
  249. <!--#分页的省略显示 kingadmin/templatetags/kingadmin_tags.pydef pag_omit(request,admin_obj):-->
  250. {% pag_omit request admin_obj %}
  251. <!--如果有下一页-->
  252. {% if admin_obj.querysets.has_next %}
  253. {## ————————18PerfectCRM实现King_admin搜索关键字————————#}
  254. {## ————————17PerfectCRM实现King_admin单列排序————————#}
  255. {# <li><a href="?page={{ admin_obj.querysets.next_page_number }}{% generate_filter_url admin_obj %}"#}
  256. {# aria-label="Previous"><span aria-hidden="true">&raquo;</span></a></li>#}
  257.  
  258. {#<li><a href="?page={{ admin_obj.querysets.next_page_number }}{% generate_order_by_url request %}{% generate_filter_url admin_obj %}"#}
  259. {# aria-label="Previous"><span aria-hidden="true">下页</span></a></li>#}
  260. {## ————————17PerfectCRM实现King_admin单列排序————————#}
  261. <li><a href="?page={{ admin_obj.querysets.next_page_number }}
  262. {% generate_order_by_url request %}{% generate_filter_url admin_obj %}&_q={% get_search_key request %}"
  263. aria-label="Previous"><span aria-hidden="true">下页</span></a></li>
  264. {## ————————18PerfectCRM实现King_admin搜索关键字————————#}
  265.  
  266. {% else %}
  267. <li class="disabled"><a href="#" aria-label="Previous"><span aria-hidden="true">&raquo;</span></a>
  268. </li>
  269. {% endif %}
  270. </ul>
  271. </nav>
  272. </div>
  273. {## ————————14PerfectCRM实现King_admin分页的省略显示————————#}
  274.  
  275. {% endblock %}
  276. {## ————————08PerfectCRM实现King_admin显示注册表的字段表头————————#}

{#table_data_list.html#}


如果感觉本章博客对您有帮助,请尽情打赏吧!

Django项目:CRM(客户关系管理系统)--64--54PerfectCRM实现CRM客户报名链接的更多相关文章

  1. 文献综述二十:基于UML技术的客户关系管理系统实现

    一.基本信息 标题:基于UML技术的客户关系管理系统实现 时间:2015 出版源:电子设计工程 文件分类:uml技术的研究 二.研究背景 设计出可应用与银行和储户之间沟通的客户关系管理系统,从而实现对 ...

  2. Django CRM客户关系管理系统

    CRM需求分析 随着信息化时代带来的科技创新,CRM客户关系管理系统带来的效益在已经成为很多企业提高竞争优势的一分部,CRM客户关系管理系统将企业管理和客户关系管理集成到统一的平台,其系统功能主要体现 ...

  3. Java高级项目实战02:客户关系管理系统CRM系统模块分析与介绍

    本文承接上一篇:Java高级项目实战之CRM系统01:CRM系统概念和分类.企业项目开发流程 先来CRM系统结构图: 每个模块作用介绍如下: 1.营销管理 营销机会管理:针对企业中客户的质询需求所建立 ...

  4. CRM客户关系管理系统(一)

    第一章.CRM介绍和开发流程 1.1.CRM简介 客户关系管理(CRM) 客户关系管理(customer relationship management)的定义是:企业为提高核心竞争力,利用相应的信息 ...

  5. CRM客户关系管理系统-需求概设和详设

    大概设计 大概设计就是对需求进行一个整体性分析,把需要实现的功能都列出来,对于客户关系管理系统,我们需要从角色出发,从而确定有哪些需求,最好是画个思维导图 首先我们是为培训学校这么一个场景来开发的,所 ...

  6. CRM 客户关系管理系统

    CRM(Customer Relationship Manager)客户关系管理系统 企业为提高核心竞争力,利用相应的信息技术以及互联网技术协调企业与顾客间在销售.营销和服务上的交互,从而提升其管理方 ...

  7. 客户关系管理系统(CRM)的开发过程中使用到的开发工具总结

    开发<客户关系管理系统(CRM)>软件过程,也就是一个标准的Winform程序的开发过程,我们可以通过这个典型的软件开发过程来了解目前的开发思路.开发理念,以及一些必要的高效率手段.本篇随 ...

  8. Winform开发框架之客户关系管理系统(CRM)的开发总结系列4-Tab控件页面的动态加载

    在前面介绍的几篇关于CRM系统的开发随笔中,里面都整合了多个页面的功能,包括多文档界面,以及客户相关信息的页面展示,这个模块就是利用DevExpress控件的XtraTabPage控件的动态加载实现的 ...

  9. Winform开发框架之客户关系管理系统(CRM)的开发总结系列3-客户分类和配置管理实现

    我在本系列随笔的开始,介绍了CRM系统一个重要的客户分类的展示界面,其中包含了从字典中加载分类.从已有数据中加载分类.以及分组列表中加载分类等方式的实现,以及可以动态对这些节点进行配置,实现客户分类的 ...

  10. Winform开发框架之客户关系管理系统(CRM)的开发总结系列2-基于框架的开发过程

    在上篇随笔<Winform开发框架之客户关系管理系统(CRM)的开发总结系列1-界面功能展示>中介绍了我的整个CRM系统的概貌,本篇继续本系列的文章,介绍如何基于我的<winform ...

随机推荐

  1. C++ 贪吃蛇二维

    #include <iostream> #include <conio.h> #include <windows.h> #include <time.h> ...

  2. Windows 虚拟机 VM

    VMware是全球台式电脑及资料中心虚拟化解决方案的领导厂商.VMWare Workstation是该公司出品的“虚拟 PC”软件(即:大家常说的“虚拟机”),通过它可在一台电脑上同时运行更多的Mic ...

  3. 微信公众号开发API接口大全

    在本文中,我们列出微信公众平台上可以使用的API接口以及举例如何在微信公众平台调用这些接口实现相应的功能. 接口调用说明: ① Appkey请使用的微信公众号,不要使用默认的trailuser ② 接 ...

  4. kubernetes 强制删除istio-system空间,强制删除pod

    加上这个选项 --grace-period=0 --force--grace-period=0 --force 先删除deployment,pod,svc再删除namespace > kubec ...

  5. 用连接池链接redis

    package com.itheima.utils; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; i ...

  6. (2)python tkinter-按钮.标签.文本框、输入框

    按钮 无功能按钮 Button的text属性显示按钮上的文本 tkinter.Button(form, text='hello button').pack() 无论怎么变幻窗体大小,永远都在窗体的最上 ...

  7. 在ubuntu下编写python

    一般情况下,ubuntu已经安装了python,打开终端,直接输入python,即可进行python编写. 默认为python2 如果想写python3,在终端输入python3即可. 如果需要执行大 ...

  8. PAT甲级——A1104 Sum of Number Segments【20】

    Consider a positive integer N written in standard notation with k+1 digits a​i​​ as a​k​​⋯a​1​​a​0​​ ...

  9. USACO 2009 Open Treasure Cave /// DFS||并查集 oj26215

    题目大意: 输入 p,n,t :p为地点数 判断 t 能否回到源点1 接下来n行 每行输入 a b c: a能到达b和c Sample Input 13 6 76 7 82 3 410 11 128 ...

  10. java_Properties集合

    package propertiesTest; import java.io.FileReader; import java.io.FileWriter; import java.io.IOExcep ...