Django项目:CRM(客户关系管理系统)--69--59PerfectCRM实现king_admin行内编辑

  1 #base_admin.py
  2 
  3 
  4 # ————————24PerfectCRM实现King_admin自定义操作数据————————
  5 from django.shortcuts import render,redirect
  6 # ————————24PerfectCRM实现King_admin自定义操作数据————————
  7 
  8 # ————————04PerfectCRM实现King_admin注册功能————————
  9 
 10 #Django admin 注册功能的形式
 11 # sites = {
 12 #     'crm':{
 13 #         'customers':CustomerAdmin,
 14 #         'customerfollowup':CustomerFollowUPAdmin,
 15 #     }
 16 # }
 17 
 18 class AdminRegisterException(Exception):  #自定义异常
 19     def __init__(self,msg):
 20         self.message = msg
 21 
 22 class BaseAdmin(object):#自定义方法
 23     list_display = ()  #显示的字段(不能包含ManyToManyField)
 24 
 25     # ————————11PerfectCRM实现King_admin分页显示条数————————
 26     list_per_page = 10  # 默认分页条数10
 27     # ————————11PerfectCRM实现King_admin分页显示条数————————
 28 
 29     # ————————15PerfectCRM实现King_admin多条件过滤————————
 30     list_filter = ()        # 过滤器(可以包含ManyToManyField) (注意加 逗号 , )
 31     # ————————15PerfectCRM实现King_admin多条件过滤————————
 32 
 33     # ————————18PerfectCRM实现King_admin搜索关键字————————
 34     search_fields = () #搜索(不能包含CharField)(注意加 逗号 , )
 35     # ————————18PerfectCRM实现King_admin搜索关键字————————
 36 
 37     # ————————26PerfectCRM实现King_admin自定义排序————————
 38     ordering = None    #自定义排序
 39     # ————————26PerfectCRM实现King_admin自定义排序————————
 40 
 41     # ————————27PerfectCRM实现King_admin编辑复选框————————
 42     filter_horizontal = []#复选框
 43     # ————————27PerfectCRM实现King_admin编辑复选框————————
 44 
 45     # ————————33PerfectCRM实现King_admin编辑整张表限制————————
 46     readonly_table=False#默认表单不锁定
 47     # ————————33PerfectCRM实现King_admin编辑整张表限制————————
 48 
 49     # ————————36PerfectCRM实现King_admin密码修改————————
 50     modelform_exclude_fields=[]#排除验证字段
 51     # ————————36PerfectCRM实现King_admin密码修改————————
 52 
 53     # ————————55PerfectCRM实现CRM客户报名状态颜色变化————————
 54     colored_fields = {}
 55     # ————————55PerfectCRM实现CRM客户报名状态颜色变化————————
 56 
 57     # ————————59PerfectCRM实现king_admin行内编辑————————
 58     list_editable = []#可编辑
 59     # ————————59PerfectCRM实现king_admin行内编辑————————
 60 
 61     # ————————24PerfectCRM实现King_admin自定义操作数据————————
 62     actions = []#自定功能
 63 
 64     default_actions = ["delete_selected",]  #默认删除的函数
 65     #默认删除的函数
 66     def delete_selected(self,request,queryset):
 67         # from django.shortcuts import render, redirect
 68         print("goint to delete ",queryset)
 69         app_name=self.model._meta.app_label#app名
 70         model_name=self.model._meta.model_name#表名
 71         objs=queryset#类对象
 72         action=request._admin_action
 73         print(action,'<-------action')
 74         
 75         # ————————33PerfectCRM实现King_admin编辑整张表限制————————
 76         if self.readonly_table:
 77             errors={'锁定的表单':'当前表单已经锁定,不可进行批量删除操作!'}
 78         else:
 79             errors={}
 80         # ————————33PerfectCRM实现King_admin编辑整张表限制————————
 81 
 82         if request.POST.get('delete_confirm')=='yes': #{#table_delete.html#}
 83 
 84             # ————————33PerfectCRM实现King_admin编辑整张表限制————————
 85             if not self.readonly_table:
 86             # ————————33PerfectCRM实现King_admin编辑整张表限制————————
 87                 queryset.delete()
 88                 return redirect('/king_admin/%s/%s/'%(app_name,model_name))
 89             else:
 90                 return redirect('/king_admin/%s/%s/' % (app_name, model_name))
 91         selected_ids=','.join([str(i.id) for i in queryset])
 92         print(selected_ids,'<---selected_ids')
 93         objs=queryset
 94         return render(request,"king_admin/table_delete.html", locals())  #返回删除页
 95     delete_selected.short_description = "默认批量删除"
 96     # ————————24PerfectCRM实现King_admin自定义操作数据————————
 97 
 98     # ————————28PerfectCRM实现King_admin编辑限制————————
 99     readonly_fields = [] # 不可修改
100 
101     # ————————29PerfectCRM实现King_admin编辑自定义限制————————
102     #默认表单验证 全部 可重写
103     def default_form_validation(self,request):
104         #用户可以在此进行自定义的表单验证,相当于django form 的clean方法
105         '''默认表单验证  ==  django form 的clean方法'''
106         pass
107     # ————————29PerfectCRM实现King_admin编辑自定义限制————————
108     # ————————28PerfectCRM实现King_admin编辑限制————————
109 
110     
111 # ————————05PerfectCRM实现King_admin注册功能获取内存————————
112 class AdminSite(object):
113     def __init__(self):
114         self.registered_sites = {}   #传到views 里调用
115     def register(self,model,admin_class=None): #默认值None 使用 BaseAdmin
116         app_name = model._meta.app_label#用内置方法获取 APP名字 (crm)
117         model_name = model._meta.model_name#用内置方法获取 表名  (Customer)
118         if app_name not in self.registered_sites:
119             self.registered_sites[app_name] = {} #创建  crm={}
120         if model_name in self.registered_sites[app_name]:
121             raise AdminRegisterException("app [%s] model [%s] has already registered!异常"
122                                                  %(app_name,model_name))#自定义异常,
123         if not  admin_class:
124             admin_class = BaseAdmin  #默认值None 使用 BaseAdmin
125         # self.registered_sites[app_name][model_name] = admin_class #注册APP
126 # site = AdminSite()  # 实例化类  单例模式
127 
128 
129         # ————————05PerfectCRM实现King_admin注册功能获取内存————————
130         #registered_sites {'crm': {'customer': <class 'crm.kingadmin.CustomerAdmin'>, 'courserecord': <class 'kingadmin.base_admin.BaseAdmin'>}}
131         #把类名放到class的对象里,然后通过class的对象传到前端
132 #         admin_class.model = model
133 #         self.registered_sites[app_name][model_name] = admin_class #注册APP
134 #
135 # site = AdminSite() #实例化类  单例模式
136         # ————————05PerfectCRM实现King_admin注册功能获取内存————————
137 
138         # ————————06PerfectCRM实现King_admin注册功能获取内存优化处理————————
139         #没有实例化会使用同一个内存地址
140         admin_obj = admin_class()  #先实例化
141         admin_obj.model = model    #参数赋值给实例
142         self.registered_sites[app_name][model_name] = admin_obj#注册APP
143         #实例化后,调用会使用不同的内存地址
144 
145 site = AdminSite() #实例化类  单例模式
146         # ————————06PerfectCRM实现King_admin注册功能获取内存优化处理————————
147         
148 # registered_sites={}
149 # def register(model,admin_class=None): #默认值None 使用 BaseAdmin
150 #     app_name = model._meta.app_label#用内置方法获取 APP名字 (crm)
151 #     model_name = model._meta.model_name#用内置方法获取 表名  (Customer)
152 #     if app_name not in registered_sites:
153 #         registered_sites[app_name] = {} #创建  crm={}
154 #     if model_name in registered_sites[app_name]:
155 #         raise AdminRegisterException("app [%s] model [%s] has already registered!异常"
156 #                                              %(app_name,model_name))#自定义异常
157 #     if not admin_class:
158 #         admin_class = BaseAdmin  #默认值None 使用class BaseAdmin
159 #     registered_sites[app_name][model_name] = admin_class #注册APP
160 
161 # ————————05PerfectCRM实现King_admin注册功能获取内存————————
162 
163 # ————————04PerfectCRM实现King_admin注册功能————————
#base_admin.py

  1 # views
  2 
  3 # ————————02PerfectCRM创建ADMIN页面————————
  4 from django.shortcuts import render
  5 
  6 # ————————04PerfectCRM实现King_admin注册功能————————
  7 # from django import conf #配置文件
  8 # print("dj conf:",conf) #配置文件
  9 # print("dj conf:",conf.settings)#配置文件.设置
 10 # ————————04PerfectCRM实现King_admin注册功能————————
 11 
 12 # ————————04PerfectCRM实现King_admin注册功能————————
 13 from king_admin import app_config  # 自动调用  动态加载类和函数
 14 # ————————04PerfectCRM实现King_admin注册功能————————
 15 
 16 # ————————04PerfectCRM实现King_admin注册功能————————
 17 # from king_admin.base_admin import registered_sites # registered_sites={}
 18 from king_admin import base_admin
 19 # ————————04PerfectCRM实现King_admin注册功能————————
 20 
 21 # ————————11PerfectCRM实现King_admin基本分页————————
 22 from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger  # 分页功能
 23 # ————————11PerfectCRM实现King_admin基本分页————————
 24 
 25 # ————————46PerfectCRM实现登陆后页面才能访问————————
 26 from  django.contrib.auth.decorators import login_required
 27 
 28 
 29 # ————————46PerfectCRM实现登陆后页面才能访问————————
 30 
 31 def app_index(request):
 32     # ————————04PerfectCRM实现King_admin注册功能————————
 33     # for app in conf.settings.INSTALLED_APPS:
 34     #     print(app)#循环打印 配置文件.设置.安装应用程序#.Perfectcustomersettings里的INSTALLED_APPS列表
 35     # ————————04PerfectCRM实现King_admin注册功能————————
 36 
 37     # ————————04PerfectCRM实现King_admin注册功能————————
 38     # return render(request, 'king_admin/app_index.html')
 39     # print("registered_sites",registered_sites)
 40     # return render(request, 'king_admin/app_index.html')
 41     # ————————04PerfectCRM实现King_admin注册功能————————
 42 
 43     # ————————04PerfectCRM实现King_admin注册功能————————
 44     # print("registered_sites", base_admin.registered_sites)
 45     # return render(request, 'king_admin/app_index.html')
 46     # ————————04PerfectCRM实现King_admin注册功能————————
 47 
 48     # ————————05PerfectCRM实现King_admin注册功能获取内存————————
 49     print("registered_sites", base_admin.site.registered_sites)
 50     return render(request, 'king_admin/app_index.html', {"site": base_admin.site})
 51 
 52 
 53 # ————————05PerfectCRM实现King_admin注册功能获取内存————————
 54 
 55 # ————————02PerfectCRM创建ADMIN页面————————
 56 
 57 # ————————13PerfectCRM实现King_admin分页页数————————
 58 # 处理def table_data_list(request,app_name,model_name):里的内容,
 59 def filter_querysets(request, queryset):
 60     condtions = {}  # 定义一个字典用来存过滤的条件
 61     for k, v in request.GET.items():  # 不需要空的,判断是否为空
 62         # ————————18PerfectCRM实现King_admin搜索关键字————————
 63         # ————————17PerfectCRM实现King_admin单列排序————————
 64         # if k=="page":continue##kingadmin分页功能
 65 
 66         # if k=="page":continue##kingadmin分页功能 #写法一
 67         # elif k=="_o":continue##kingadmin排序功能  <a href="?_o={{ column }}">{{ column }}</a>
 68 
 69         # if k in ("page","_o") :continue #kingadmin分页功能   #kingadmin排序功能   #写法二
 70 
 71         # if k == "page"or k == "_o": #保留的分页关键字 和  排序关键字 #写法三
 72         #     continue #continue是结束单次循环
 73         # ————————17PerfectCRM实现King_admin单列排序————————
 74         if k in ("page", "_o", "_q"): continue  # kingadmin分页,排序,搜索#判断标签是否存在 自定义的名称
 75         # ————————18PerfectCRM实现King_admin搜索关键字————————
 76 
 77 
 78         # ————————15PerfectCRM实现King_admin多条件过滤————————
 79         if v:
 80             condtions[k] = v  # 进行配对字典
 81             # ————————15PerfectCRM实现King_admin多条件过滤————————
 82     query_res = queryset.filter(**condtions)
 83 
 84     return query_res, condtions
 85 
 86 
 87 # ————————13PerfectCRM实现King_admin分页页数————————
 88 
 89 # ————————59PerfectCRM实现king_admin行内编辑————————
 90 from  king_admin import form
 91 
 92 
 93 def batch_update(request, editable_data, admin_obj):
 94     """table objects batch update , for list_editable feature"""
 95     errors = []  # 错误信息
 96     for row_data in editable_data:
 97         obj_id = row_data.get('id')  # 获取这行ID号
 98         try:
 99             if obj_id:
100                 print("如果有ID编辑数据:", row_data, list(row_data.keys()))
101                 obj = admin_obj.model.objects.get(id=obj_id)  # 获取编辑的ID
102                 model_form = form.create_form(admin_obj.model, list(row_data.keys()),
103                                               admin_obj, request=request, partial_update=True)  # 进行数据验证处理
104                 form_obj = model_form(instance=obj, data=row_data)  # 编辑的ID #验证的内容
105                 if form_obj.is_valid():  # 验证通过
106                     form_obj.save()  # 保存新内容
107                     print('保存。。。。')
108 
109                 else:
110                     print("可编辑列表形式", row_data, form_obj.errors)
111 
112                     errors.append([form_obj.errors, obj])  # 添加错误信息
113 
114                     # for column in row_data:
115                     #     if column != "id":#id no need change
116                     #         #print("-----column",column,row_data[column],type(row_data[column]))
117                     #         if row_data[column] in ('True','False'):
118                     #             if obj._meta.get_field(column).get_internal_type() == "BooleanField":
119                     #                 setattr(obj, column, eval(row_data[column]))
120                     #                 #print("setting column [%s] to [%s]" %(column,row_data[column]), eval(row_data[column]))
121                     #             else:
122                     #                 setattr(obj, column, row_data[column])
123                     #         else:
124                     #             setattr(obj,column,row_data[column])
125                     #
126                     # obj.save()
127 
128         # except Exception as e:
129         except KeyboardInterrupt as e:
130             return False, [e, obj]
131     if errors:
132         return False, errors
133     return True, []
134 
135 
136 # ————————59PerfectCRM实现king_admin行内编辑————————
137 
138 # ————————08PerfectCRM实现King_admin显示注册表的字段表头————————
139 @login_required  # 登陆后页面才能访问
140 def table_data_list(request, app_name, model_name):
141     # 通过2个参数到base_admin里获取class AdminRegisterException(Exception): 的对象
142     admin_obj = base_admin.site.registered_sites[app_name][model_name]  # base_admin
143 
144     # ————————24PerfectCRM实现King_admin自定义操作数据————————
145     if request.method == "POST":  # 批量操作
146         action = request.POST.get("action_select")  # 要调用的自定制功能函数
147         selected_ids = request.POST.get("selected_ids")  # 前端提交的数据
148         print(selected_ids, type(selected_ids), "selected_ids-----")
149         # if type(selected_ids)!='str':
150         # selected_ids = json.loads(selected_ids)#进行转换数据
151         print(selected_ids, type(action), action, "selected_ids==========")
152         # print("action:",selected_ids,action)
153         # ————————59PerfectCRM实现king_admin行内编辑————————
154         import json
155         editable_data = request.POST.get("editable_data")  # 获取前端可编辑的数据
156         print('编辑数据:', editable_data)
157         if editable_data:  # for list editable
158             editable_data = json.loads(editable_data)  # 进行转换数据
159             # print("editable",editable_data)
160             res_state, errors = batch_update(request, editable_data, admin_obj)  # 进行部分更新操作
161         else:
162             # ————————59PerfectCRM实现king_admin行内编辑————————
163             if selected_ids:
164                 # selected_ids = json.loads(selected_ids)#进行转换数据
165                 selected_objs = admin_obj.model.objects.filter(id__in=selected_ids.split(','))  # 返回之前所选中的条件
166             else:
167                 raise KeyError('错误,没有选择对象!')
168 
169             if hasattr(admin_obj, action):
170                 action_func = getattr(admin_obj, action)  # 如果admin_obj 对象中有属性action 则打印self.action的值,否则打印'not find'
171                 request._admin_action = action  # 添加action内容
172                 print(request._admin_action, action, '<--------')
173             return action_func(request, selected_objs)
174     # ————————24PerfectCRM实现King_admin自定义操作数据————————
175 
176 
177     # ————————09PerfectCRM实现King_admin显示注册表的内容————————
178     admin_obj.querysets = admin_obj.model.objects.all()  # 取数据 传到 前端
179     # ————————09PerfectCRM实现King_admin显示注册表的内容————————
180 
181     # ————————11PerfectCRM实现King_admin分页显示条数————————
182     # from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger  # 分页功能#放在顶上导入
183     obj_list = admin_obj.model.objects.all()  # 取数据 传到 前端  #base_admin  #获取传过来的所有对象
184 
185     # ————————13PerfectCRM实现King_admin分页页数————————
186     queryset, condtions = filter_querysets(request, obj_list)  # base_admin   # 调用条件过滤
187     # ————————13PerfectCRM实现King_admin分页页数————————
188 
189     # ————————18PerfectCRM实现King_admin搜索关键字————————
190     queryset = get_queryset_search_result(request, queryset, admin_obj)  ##搜索后
191     # ————————18PerfectCRM实现King_admin搜索关键字————————
192 
193     # ————————26PerfectCRM实现King_admin自定义排序————————
194     sorted_queryset = get_orderby(request, queryset, admin_obj)  # 排序后的结果
195     # ————————17PerfectCRM实现King_admin单列排序————————
196     # sorted_queryset = get_orderby(request, queryset) #排序后的结果
197     # ————————15PerfectCRM实现King_admin多条件过滤————————
198     # paginator = Paginator(obj_list,admin_obj.list_per_page)  #kingadmin里class CustomerAdmin(BaseAdmin):
199     # paginator = Paginator(queryset, admin_obj.list_per_page)
200     # ————————15PerfectCRM实现King_admin多条件过滤————————
201     paginator = Paginator(sorted_queryset, admin_obj.list_per_page)
202     # ————————17PerfectCRM实现King_admin单列排序————————
203     # ————————26PerfectCRM实现King_admin自定义排序————————
204 
205 
206     page = request.GET.get('page')
207     try:
208         objs = paginator.page(page)  # 当前的页面的数据
209     except PageNotAnInteger:
210         # 如果页面不是一个整数,交付第一页。
211         objs = paginator.page(1)
212     except EmptyPage:
213         # 如果页面的范围(例如9999),交付最后一页的搜索结果。
214         objs = paginator.page(paginator.num_pages)
215     admin_obj.querysets = objs  # base_admin
216 
217     # ————————13PerfectCRM实现King_admin分页页数————————
218     admin_obj.filter_condtions = condtions  # base_admin
219     # ————————13PerfectCRM实现King_admin分页页数————————
220 
221     # ————————11PerfectCRM实现King_admin分页显示条数————————
222 
223     return render(request, "king_admin/table_data_list.html", locals())
224 
225 
226 # ————————08PerfectCRM实现King_admin显示注册表的字段表头————————
227 
228 
229 
230 
231 # ————————17PerfectCRM实现King_admin单列排序————————
232 # def get_orderby(request,queryset):
233 # order_by_key = request.GET.get("_o")   #获取URL里有没有("_o") <a href="?_o={{ column }}">{{ column }}</a>
234 # #页面刚开始没有这个值
235 # if order_by_key != None:  #有("_o")这个值 就进行排序
236 #     query_res = queryset.order_by(order_by_key)
237 # else: #没有就不排序,直接返回
238 #     query_res = queryset
239 # return query_res     #排序时会错
240 
241 # orderby_key = request.GET.get("_o")
242 # if orderby_key:
243 #     return  queryset.order_by(orderby_key)
244 # return  queryset
245 
246 # 在table_data_list添加
247 # def table_data_list(request,app_name,model_name): #详细列表
248 # sorted_queryset = get_orderby(request, queryset)
249 # 在filter_querysets添加
250 # if k == "page"or k == "_o": #保留的分页关键字 和  排序关键字
251 # ————————17PerfectCRM实现King_admin单列排序————————
252 
253 # ————————26PerfectCRM实现King_admin自定义排序————————
254 def get_orderby(request, queryset, admin_obj):
255     orderby_key = request.GET.get("_o")
256     # order_by_key1=order_by_key.strip()
257     if orderby_key:  # 有获取到字段
258         query_res = queryset.order_by(orderby_key.strip())  # .strip()默认删除空白符(包括'
', '
',  '	',  ' ')
259     else:
260         if admin_obj.ordering:  # 查看kingadmin‘有没有    ordering = '-qq'  # 自定义排序
261             query_res = queryset.order_by("%s" % admin_obj.ordering)
262         else:
263             query_res = queryset.order_by('-id')  # 默认倒序
264     return query_res
265 
266 
267 # 在table_data_list添加
268 # def table_data_list(request,app_name,model_name): #详细列表
269 # sorted_queryset = get_orderby(request, queryset, admin_obj)  # 排序后的结果
270 # ————————26PerfectCRM实现King_admin自定义排序————————
271 
272 
273 # ————————18PerfectCRM实现King_admin搜索关键字————————
274 from django.db.models import Q
275 
276 
277 def get_queryset_search_result(request, queryset, admin_obj):
278     search_key = request.GET.get("_q", "")  # 取定义名,默认为空
279     q_obj = Q()  # 多条件搜索 #from django.db.models import Q
280     q_obj.connector = "OR"  # or/或 条件
281     for column in admin_obj.search_fields:  # 搜索目标crm/kingadmin里class CustomerAdmin(BaseAdmin):search_fields = ('name','qq',)
282         q_obj.children.append(("%s__contains" % column, search_key))  # 运态添加多个条件
283     res = queryset.filter(q_obj)  # 对数据库进行条件搜索
284     return res  # 返回结果
285 
286 
287 # 在table_data_list添加
288 # def table_data_list(request,app_name,model_name): #详细列表
289 #      queryset = get_queryset_search_result(request,queryset,admin_obj)
290 # ————————18PerfectCRM实现King_admin搜索关键字————————
291 
292 
293 # ————————19PerfectCRM实现King_admin数据修改————————
294 from  king_admin import forms
295 
296 
297 # 修改内容
298 # def table_change(request,app_name,model_name):
299 #     obj_form = forms.CustomerModelForm()  #创建一个空表单
300 #     return render(request,"kingadmin/table_change.html",locals())
301 @login_required  # 登陆后页面才能访问
302 def table_change(request, app_name, model_name, obj_id):
303     admin_obj = base_admin.site.registered_sites[app_name][model_name]  # 获取表对象
304     # kingadmin/forms.py里def CreateModelForm(request,admin_obj):
305     model_form = forms.CreateModelForm(request, admin_obj=admin_obj)  ##modelform 生成表单 加验证
306     # obj_form = model_form()  # 表单
307     obj = admin_obj.model.objects.get(id=obj_id)  # 根据ID获取数据记录
308 
309     # ————————28PerfectCRM实现King_admin编辑限制————————
310     # ————————20PerfectCRM实现King_admin数据修改美化————————
311     # #面向对象最重要的概念就是类(Class)和实例(Instance),必须牢记类是抽象的模板,比如Student类,而实例是根据类创建出来的一个个具体的“对象”,每个对象都拥有相同的方法,但各自的数据可能不同。
312     # obj_form = model_form(instance=obj)  # 数据传入表单
313 
314     if request.method == "GET":  # 如果是 GET 表示 是添加记录
315         obj_form = model_form(instance=obj)  # 数据传入表单
316     elif request.method == "POST":  # 如果是 POST 表示 是修改后的数据
317         obj_form = model_form(instance=obj, data=request.POST)  # 更新数据
318         if obj_form.is_valid():
319             obj_form.save()
320     # ————————20PerfectCRM实现King_admin数据修改美化————————
321     # ————————28PerfectCRM实现King_admin编辑限制————————
322 
323     return render(request, "king_admin/table_change.html", locals())
324 
325 
326 # ————————19PerfectCRM实现King_admin数据修改————————
327 
328 
329 # ————————21PerfectCRM实现King_admin查看页面美化————————
330 # 单个具体app页面
331 @login_required  # 登陆后页面才能访问
332 def table_index(request, app_name):
333     bases = base_admin.site.registered_sites[app_name]  # 取出对应app对象
334     return render(request, 'king_admin/table_index.html', {"site": bases, 'app_name': app_name})
335 
336 
337 # ————————21PerfectCRM实现King_admin查看页面美化————————
338 
339 # ————————22PerfectCRM实现King_admin数据添加————————
340 from django.shortcuts import redirect  # kingadmin添加内容
341 
342 
343 @login_required  # 登陆后页面才能访问
344 def table_add(request, app_name, model_name):
345     admin_obj = base_admin.site.registered_sites[app_name][model_name]  # 获取表对象
346     # ————————32PerfectCRM实现King_admin添加不进行限制————————
347     admin_obj.is_add_form = True  # 表示为新增表单
348     # ————————32PerfectCRM实现King_admin添加不进行限制————————
349     model_form = forms.CreateModelForm(request, admin_obj=admin_obj)  ##modelform 生成表单 加验证
350     if request.method == "GET":
351         obj_form = model_form()  # 跳转过来的为空
352     elif request.method == "POST":
353         obj_form = model_form(data=request.POST)  # 创建数据
354 
355         # ————————37PerfectCRM实现King_admin添加用户时密码加密————————
356         password = request.POST.get('password')  # 取前端输入的密码
357         email = request.POST.get('email')  # 取前端输入的邮箱
358         # ————————37PerfectCRM实现King_admin添加用户时密码加密————————
359 
360         if obj_form.is_valid():
361             # ————————32PerfectCRM实现King_admin添加不进行限制————————
362             # obj_form.save()
363             try:
364                 obj_form.save()  # 表单验证通过保存
365             except Exception as e:
366                 return redirect("/king_admin/%s/%s/" % (app_name, model_name))  # 转到之前的页面
367                 # ————————32PerfectCRM实现King_admin添加不进行限制————————
368         if not obj_form.errors:  # 没有错误返回原来的页面
369 
370             # ————————37PerfectCRM实现King_admin添加用户时密码加密————————
371             if email:
372                 obj = admin_obj.model.objects.filter(email=email).first()  # 对象
373                 obj.set_password(password)  # 加密
374             try:
375                 obj.save()  # 表单验证通过保存
376             except Exception as e:
377                 return redirect("/king_admin/%s/%s/" % (app_name, model_name))
378             # ————————37PerfectCRM实现King_admin添加用户时密码加密————————
379 
380             # from django.shortcuts import redirect
381             return redirect("/king_admin/%s/%s/" % (app_name, model_name))
382     return render(request, "king_admin/table_add.html", locals())
383 
384 
385 # ————————22PerfectCRM实现King_admin数据添加————————
386 
387 
388 # ————————23PerfectCRM实现King_admin数据删除————————
389 @login_required  # 登陆后页面才能访问
390 def table_delete(request, app_name, model_name, obj_id):
391     admin_obj = base_admin.site.registered_sites[app_name][model_name]  # 表类
392     objs=admin_obj.model.objects.filter(id=obj_id)#类的对象
393 
394     # ————————33PerfectCRM实现King_admin编辑整张表限制————————
395     # if request.method=='POST':
396     #     objs.delete()#删除
397     #     return redirect("/king_admin/%s/%s/" % (app_name,model_name))#转到列表页面
398 
399     app_name=app_name
400     if admin_obj.readonly_table:
401         errors={'锁定的表单':'该表单:<%s>,已经锁定,不能删除当前记录!'%model_name}
402     else:
403         errors={}
404     if request.method=='POST':
405         if  not admin_obj.readonly_table:
406             objs.delete()#删除
407             return redirect("/king_admin/%s/%s/" % (app_name,model_name))#转到列表页面
408     # ————————33PerfectCRM实现King_admin编辑整张表限制————————
409 
410 
411     return render(request, "king_admin/table_delete.html", locals())  # locals 返回一个包含当前范围的局部变量字典。
412 
413 
414 # ————————23PerfectCRM实现King_admin数据删除————————
415 
416 # ————————36PerfectCRM实现King_admin密码修改————————
417 # 密码修改
418 @login_required  # 登陆后页面才能访问
419 def password_reset(request, app_name, model_name, obj_id):
420     admin_obj = base_admin.site.registered_sites[app_name][model_name]  # 表类
421     model_form = forms.CreateModelForm(request, admin_obj=admin_obj)  # modelform 生成表单 加验证
422     obj = admin_obj.model.objects.get(id=obj_id)  # 类表的对象
423     errors = {}  # 错误提示
424     if request.method == 'POST':
425         _password1 = request.POST.get('password1')  # 获取页面输入的值
426         _password2 = request.POST.get('password2')  # 获取页面输入的值
427         if _password1 == _password2:
428             if len(_password1) > 5:
429                 obj.set_password(_password1)  # 继承Django方法 #加密
430                 obj.save()  # 保存
431                 return redirect(request.path.rstrip('password/') + ('/change/'))  # 替换URL名
432             else:
433                 errors['password_too_short'] = '必须不少于6字符'
434         else:
435             errors['invalid_password'] = '两次输入的密码不一样'  # 密码不一致
436 
437     return render(request, "king_admin/password_reset.html", locals())  # locals 返回一个包含当前范围的局部变量字典。
438 
439 
440 # ————————36PerfectCRM实现King_admin密码修改————————
441 
442 # ————————37PerfectCRM实现King_admin添加用户时密码加密————————
443 def password_add(request, app_name, model_name):
444     return redirect("/king_admin/%s/%s/add/" % (app_name, model_name))  # 转到添加页面
445     # ————————37PerfectCRM实现King_admin添加用户时密码加密————————
# views

 1 # form.py
 2 # ————————59PerfectCRM实现king_admin行内编辑————————
 3 from django import forms
 4 from django.forms import ModelForm
 5 def __new__(cls, *args, **kwargs):
 6     # super(CustomerForm, self).__new__(*args, **kwargs)
 7     # self.fields['customer_note'].widget.attrs['class'] = 'form-control'
 8     #disabled_fields = ['qq', 'consultant']
 9     for field_name in cls.base_fields:
10         field = cls.base_fields[field_name]
11         #print("field repr",field_name,field.__repr__())
12         attr_dic = {'placeholder': field.help_text}    #占位符: 帮助文本
13         if 'BooleanField' not in field.__repr__():   #布尔字段 不在 #__repr__()返回一个对象的 string 格式
14             attr_dic.update({'class': 'form-control'})    #  更新
15             #print("-->field",field)
16             if 'ModelChoiceField' in field.__repr__(): #模型选择字段 在 #__repr__()返回一个对象的 string 格式
17                 attr_dic.update({'data-tag':field_name})    #  更新  #数据标签
18             # if 'DateTimeField' in field.__repr__():
19             #     attr_dic.update({'placeholder': field_name})
20         if cls.Meta.form_create is False:          #表单创建   #是假
21             if field_name in cls.Meta.admin.readonly_fields:   #只读的字段
22                 attr_dic['disabled'] = True      #禁用
23                 #print('----read only:',field_name)
24         field.widget.attrs.update(attr_dic)    # 更新
25         #for validators
26         if hasattr(cls.Meta.model,"clean_%s" % field_name):   #hasattr() 函数用于判断对象是否包含对应的属性。
27             clean_field_func = getattr(cls.Meta.model,"clean_%s" % field_name)  #getattr() 函数用于返回一个对象属性值。
28             setattr(cls,"clean_%s" % field_name,clean_field_func)   #setattr 函数对应函数 getatt(),用于设置属性值,该属性必须存在。
29     else:
30         if hasattr(cls.Meta.model, "clean2"): #clean2 is kingadmin's own clean method
31             clean_func = getattr(cls.Meta.model, "clean")  #getattr() 函数用于返回一个对象属性值。
32             setattr(cls, "clean" , clean_func)  #setattr 函数对应函数 getatt(),用于设置属性值,该属性必须存在。
33         else:# use default clean method
34             setattr(cls, "clean", default_clean)  #setattr 函数对应函数 getatt(),用于设置属性值,该属性必须存在。
35     return ModelForm.__new__(cls)
36 
37 def default_clean(self):  #clear()方法用于清空(或删除)字典中的所有数据项。
38     '''form defautl clean method'''
39     # print("33[41;1mrun form defautl clean method...33[0m",dir(self))
40     # print(self.Meta.admin.readonly_fields)
41     print("默认删除方法:",self.cleaned_data)
42     # print("validataion errors:",self.errors)
43     if self.Meta.admin.readonly_table is True:
44         raise forms.ValidationError(("这是一个只读的表"))
45     if self.errors:
46         raise forms.ValidationError(("请补交之前修复错误。."))
47     if self.instance.id is not None :#意味着这是一个改变形式,应该检查只读的字段
48         for field in self.Meta.admin.readonly_fields:       #循环 readonly_fields 不可修改字段
49             old_field_val = getattr(self.instance,field)    #getattr() 函数用于返回一个对象属性值。
50             form_val = self.cleaned_data.get(field)
51             print("提出不同的比较:",old_field_val,form_val)
52             if old_field_val != form_val:  #如果旧字段和新字段不相等
53                 if self.Meta.partial_update: #f可编辑的功能列表,只做部分检查
54                     if field not in  self.cleaned_data:   # 如果字段 不在  清理数据理
55                         #因为list_editable成生form时只生成了指定的几个字段,所以如果readonly_field里的字段不在,list_ediatble数据里,那也不检查了
56                         continue #continue 语句跳出本次循环
57 
58                 self.add_error(field,"Readonly Field: field should be '{value}' ,not '{new_value}' ".
59                                      format(**{'value':old_field_val,'new_value':form_val}))
60 
61 def create_form(model,fields,admin_obj,form_create=False,**kwargs):
62     class Meta:
63         pass
64     setattr(Meta,'model',model)   #  如果类自定义了__setattr__方法,当通过实例获取属性尝试赋值时,就会调用__setattr__。常规的对实例属性赋值,被赋值的属性和值会存入实例属性字典__dict__中。
65     setattr(Meta,'fields',fields)
66     setattr(Meta,'admin',admin_obj)
67     setattr(Meta,'form_create',form_create)   #表单创建
68     setattr(Meta,'partial_update',kwargs.get("partial_update"))  #f可编辑的功能列表,只做部分检查
69 
70     attrs = {'Meta':Meta}
71     name = 'DynamicModelForm'     #动态模型的形式
72     baseclasess = (ModelForm,)  #模型形式
73     model_form = type(name, baseclasess,attrs)    #type属性类型
74     setattr(model_form,'__new__',__new__) #  如果类自定义了__setattr__方法,当通过实例获取属性尝试赋值时,就会调用__setattr__。常规的对实例属性赋值,被赋值的属性和值会存入实例属性字典__dict__中。
75 
76     if kwargs.get("request"): #对表单验证器
77         setattr(model_form,'_request',kwargs.get("request"))   #将给定对象命名属性设置为指定的值。
78     #print(model_form)
79     return model_form
80 # ————————59PerfectCRM实现king_admin行内编辑————————
# form.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 
 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 # ————————59PerfectCRM实现king_admin行内编辑————————
104 def render_list_editable_column(admin_obj,obj, column_obj):    #处理def build_table_row(admin_obj,obj,request):的行内编辑内容
105     #print(table_obj,row_obj,field_obj,field_obj.name,field_obj.get_internal_type())
106     data_type=("PositiveSmallIntegerField","SmallIntegerField","CharField","EmailField","TextField",'ForeignKey')
107     # 'BooleanField','   # "IntegerField", 'BigIntegerField', "BinaryField",   "FileField", "ImageField", "NullBooleanField", "URLField"
108     # 'DateField, "DecimalField"  , "TimeField", ,"AutoField" ,  ,"OneToOneField" "ManyToManyField"
109     if column_obj.get_internal_type() in data_type : #检测数据库类型
110         column_data = column_obj.value_from_object(obj)
111         if not column_obj.choices and column_obj.get_internal_type() != "ForeignKey" :   #如果不是选择框类型和外健框类型
112             column = '''<input data-tag='editable' type='text' name='%s' value='%s' >''' %
113                      (column_obj.name,
114                       column_obj.value_from_object(obj) or '')  #返回这个字段的值在给定的模型实例。
115         else:
116             # if field_obj.get_internal_type() == "ForeignKey":
117             #     column = '''<select data-tag='editable' class='form-control'  name='%s' >'''%field_obj.name
118             # else:
119             column = '''<select data-tag='editable' class='form-control'  name='%s' >'''%column_obj.name   #如果是选择框类型和外健框类型
120             for option in column_obj.get_choices(): #返回选择一个默认的空白的选择包括,使用SelectField选择这个领域。
121                 if option[0] == column_data:
122                     selected_attr = "selected"
123                 else:
124                     selected_attr = ''
125                 column += '''<option value='%s' %s >%s</option>'''% (option[0],selected_attr,option[1])
126             column += "</select>"
127     elif column_obj.get_internal_type() == 'BooleanField':  #如果是勾选类型
128         column_data = column_obj.value_from_object(obj)
129         if column_data == True:  #如果前端返回的数据等于真
130             checked = 'checked'  #勾选框显示打勾
131         else:
132             checked = ''     #勾选框显示空
133         column = '''<input data-tag='editable'   type='checkbox' name='%s' value="%s"  %s> ''' %(column_obj.name,column_data,checked)
134     else:
135         column = column_obj.value_from_object(obj)   ##返回这个字段的值在给定的模型实例。
136     return column
137 # ————————59PerfectCRM实现king_admin行内编辑————————
138 
139 # ————————54PerfectCRM实现CRM客户报名链接————————
140 from django.utils.safestring import mark_safe #使用mark_safe函数标记后,django将不再对该函数的内容进行转义
141 from django.core.exceptions import FieldDoesNotExist
142 @register.simple_tag
143 def build_table_row(admin_obj,obj):#通过kingadmin_tags在后台处理 再传到前端
144     row_ele = "" #为了生成一整行返回前端
145     # ————————54PerfectCRM实现CRM客户报名链接————————
146     column_not=[]#表示不是表中字段列表
147     # ————————54PerfectCRM实现CRM客户报名链接————————
148 
149     if admin_obj.list_display:#如果不为空,有在crm/kingadmin.py注册site.register(models.Customer,CustomerAdmin)
150         # ————————19PerfectCRM实现King_admin数据修改————————
151         #循环所有 要显示 的字符串 进行反射 展示 字段
152         # for column in admin_obj.list_display: #循环base_admin里class BaseAdmin下list_display = ()
153         for index, column in enumerate(admin_obj.list_display):  # 转为列表取 下标 , 字段名
154         # ————————19PerfectCRM实现King_admin数据修改————————
155             # ————————54PerfectCRM实现CRM客户报名链接————————
156             try:  #获取表中的字段
157              # ————————54PerfectCRM实现CRM客户报名链接————————
158                 column_obj = obj._meta.get_field(column)#遍历获取  传进的参数对象
159                 if column_obj.choices:#判断如果字段有choices属性
160                     #获取choices的字符串(外健)
161                     get_column_data = getattr(obj,"get_%s_display" % column) #反射,传进的参数对象,拼接字段
162                     column_data = get_column_data()#函数,拿到数据
163                 else:
164                     column_data = getattr(obj, column)#反射,
165                 # ————————10PerfectCRM实现King_admin日期优化————————
166                 if type(column_data).__name__ == 'datetime':
167                     column_data = column_data.strftime('%Y-%m-%d %H-%M-%S')
168                 # ————————10PerfectCRM实现King_admin日期优化————————
169 
170                 # ————————19PerfectCRM实现King_admin数据修改————————
171                 if index == 0: #首列
172                     # 生成一个链接 跳转到编辑页面        #Format参数是一个格式字符串(%s升级版)
173                     td_ele = '''<td><a href="/king_admin/{app_name}/{model_name}/{obj_id}/change/">{column_data}</a> </td>'''
174                                 .format(app_name=admin_obj.model._meta.app_label,
175                                         model_name=admin_obj.model._meta.model_name,
176                                         obj_id=obj.id,
177                                         column_data=column_data)
178                 # ————————55PerfectCRM实现CRM客户报名状态颜色变化————————
179                 elif column in admin_obj.colored_fields: #特定字段需要显示颜色 #如果admin_obj有配置colored_fields
180                     color_dic = admin_obj.colored_fields[column] #获取配置#字段名# 'status':{'已报名':"rgba(145, 255, 0, 0.78)",
181                     if column_data in color_dic: #如果#已报名#有在配置里
182                         td_ele = "<td style='background-color:%s'>%s</td>" % (color_dic[column_data],column_data) #颜色#已报名
183                     else:
184                         td_ele = "<td>%s</td>" % column_data
185                 # ————————55PerfectCRM实现CRM客户报名状态颜色变化————————
186 
187                 # ————————59PerfectCRM实现king_admin行内编辑————————
188                 elif column in admin_obj.list_editable:  #如果获取到king_admin配置list_editable的内容
189                     td_ele = "<td>%s</td>" % render_list_editable_column(admin_obj, obj, column_obj)  #到函数处理返回
190                 # ————————59PerfectCRM实现king_admin行内编辑————————
191                 
192                 else:
193                     td_ele = '''<td>%s</td>''' % column_data
194                 # td_ele = '''<td>%s</td>''' % column_data  #把反射来的值 拼接字符串 生成<td>
195                 # ————————19PerfectCRM实现King_admin数据修改————————
196             # ————————54PerfectCRM实现CRM客户报名链接————————
197             except FieldDoesNotExist as e:  # 如果没有获取到
198                 if hasattr(admin_obj, column):  # 从自定义的函数中取值
199                     column_func = getattr(admin_obj, column)
200                     admin_obj.instance = obj  # 对象加入
201 
202                     column_not.append(column)  # 加入非表中字段列表,
203                     admin_obj.column_not = column_not  # 对象加入
204                     column_data = column_func()
205                     print('column_data', column_data)
206                     td_ele = '''<td>%s</td>''' % column_data
207             # ————————54PerfectCRM实现CRM客户报名链接————————
208             row_ele += td_ele    #把 <td>  拼接到上面到空字符串
209     else:
210         row_ele +="<td>%s</td>" %obj  #把<td>拼接到上面到空字符串,crm/models.py里 def __str__(self):的返回值
211     return mark_safe(row_ele) #使用mark_safe函数标记后,django将不再对该函数的内容进行转义
212 # ————————54PerfectCRM实现CRM客户报名链接————————
213 # ————————54PerfectCRM实现CRM客户报名链接————————
214 ##表中自定verbose_name列名
215 @register.simple_tag
216 def verbose_name_set(admin_obj,column):
217     try:
218         verbose_name=admin_obj.model._meta.get_field(column).verbose_name.upper()#获取别名
219         print(verbose_name,'verbose_name_set')
220         print(admin_obj.model._meta,'all')
221     except FieldDoesNotExist as e:
222         verbose_name=getattr(admin_obj,column).display_name.upper()
223     return verbose_name
224 # ————————54PerfectCRM实现CRM客户报名链接————————
225 
226 
227 
228 # ————————13PerfectCRM实现King_admin分页页数————————
229 #分页功能kingadmin/templates/kingadmin/table_data_list.html里 <a href="?page={{ page }}{%  generate_filter_url admin_obj %}">{{ page }}
230 @register.simple_tag
231 def generate_filter_url(admin_obj): #拼接URL
232     url = ''
233     for k,v in admin_obj.filter_condtions.items():
234         url += "&%s=%s" %(k,v )
235     return url
236 # ————————13PerfectCRM实现King_admin分页页数————————
237 
238 # ————————14PerfectCRM实现King_admin分页的省略显示————————
239 #分页的省略显示
240 @register.simple_tag
241 def pag_omit(request,admin_obj):#传入当前页面值
242     rest=''#大字符串
243     # ————————18PerfectCRM实现King_admin搜索关键字————————
244     search_key = get_search_key(request)  # 搜索
245     # ————————18PerfectCRM实现King_admin搜索关键字————————
246     # ————————17PerfectCRM实现King_admin单列排序————————
247     order_by_url = generate_order_by_url(request)  # 排序
248     # ————————17PerfectCRM实现King_admin单列排序————————
249     # ————————15PerfectCRM实现King_admin多条件过滤————————
250     filters = generate_filter_url(admin_obj)  # 分页
251     # ————————15PerfectCRM实现King_admin多条件过滤————————
252     add_tags=False#标志位
253     for pages in admin_obj.querysets.paginator.page_range:
254         #   前两页    或   后  两页                                       或    当前页的前后页
255         if pages < 3 or pages>admin_obj.querysets.paginator.num_pages -2 or abs(admin_obj.querysets.number -pages) <=2:
256             #样式
257             add_tags=False
258             ele_class=''  #颜色
259             if pages == admin_obj.querysets.number: #--如果是当前页码,颜色加深 不进链接跳转--
260                 ele_class="active"    #颜色加深
261             # ————————18PerfectCRM实现King_admin搜索关键字————————
262             # ————————17PerfectCRM实现King_admin单列排序————————
263             # ————————15PerfectCRM实现King_admin多条件过滤————————
264             # rest+='''<li class="%s"><a href="?page=%s">%s</a></li>'''%(ele_class,pages,pages)  #--拼接URL--
265             # rest+='''<li class="%s"><a href="?page=%s%s">%s</a></li>'''%(ele_class,pages,filters,pages)  #--拼接URL--
266             # ————————15PerfectCRM实现King_admin多条件过滤————————
267             # rest+='''<li class="%s"><a href="?page=%s%s%s">%s<span class="sr-only">(current)</span></a></li>'''
268             #         %(ele_class,pages,order_by_url,filters,pages)
269             # ————————17PerfectCRM实现King_admin单列排序————————
270             rest+='''<li class="%s"><a href="?page=%s%s%s&_q=%s">%s<span class="sr-only">(current)</span></a></li>'''
271                     %(ele_class,pages,order_by_url,filters,search_key,pages)
272             # ————————18PerfectCRM实现King_admin搜索关键字————————
273         else:#其他的用省略号表示
274             if add_tags==False:#如果不是标志位的页面
275                 rest+='<li><a>...</a></li>'
276                 add_tags=True#标志位为真
277     return mark_safe(rest)  #使用mark_safe函数标记后,django将不再对该函数的内容进行转义
278 
279 # ————————14PerfectCRM实现King_admin分页的省略显示————————
280 
281 
282 
283 # # ————————15PerfectCRM实现King_admin多条件过滤————————
284 # #多条件过滤  table_data_list.html 传递参数
285 # @register.simple_tag
286 # def get_filter_field (filter_column,admin_obj):
287 #     print("admin obj",admin_obj.model ,filter_column)
288 #     field_obj = admin_obj.model._meta.get_field(filter_column)#调用内置方法
289 #     select_ele = """<select name="%s"> """ %filter_column #拼接成下拉框返回
290 #     for choice in field_obj.get_choices():#循环获取crm/models里class Customer(models.Model):下source_choices = ((0,'转介绍'),
291 #         selected_condtion = admin_obj.filter_condtions.get(filter_column)
292 #         if selected_condtion != None: #if None, 没有过滤这个条件
293 #             print("heoe....",filter_column,selected_condtion,type(selected_condtion))#类型是 整数
294 #             if selected_condtion == str(choice[0]): #就是选择的这个条件,整数转字符串
295 #                 selected = "selected"
296 #             else:
297 #                 selected = ""
298 #         else:
299 #             selected = ""
300 #
301 # #在前端把几个条件提交到后台,后台拿着条件变成一个字典,然后进行过滤,把数据返回前端,并且把条件作为字典返回后端,因为要在前端显示已经过滤的条件。
302 #         option_ele = """<option value="%s" %s>%s</option> """ % (choice[0],selected,choice[1])
303 #         select_ele +=option_ele
304 #     select_ele += "</select>"
305 #     return mark_safe(select_ele)
306 # # ————————15PerfectCRM实现King_admin多条件过滤————————
307 
308 # # ————————16PerfectCRM实现King_admin日期过滤————————
309 from django.utils.timezone import datetime,timedelta
310 @register.simple_tag
311 def get_filter_field (filter_column,admin_obj):
312     select_ele = """<select name='{filter_column}'><option  value="">---------</option>""" #标签 字符串 #拼接成下拉框返回
313     field_obj = admin_obj.model._meta.get_field(filter_column)#调用内置方法
314     selected = ''
315     if field_obj.choices:
316         for choice_item in field_obj.choices:
317             if admin_obj.filter_condtions.get(filter_column) == str(choice_item[0]):
318                 selected = "selected"
319             select_ele  +=  """<option value="%s" %s>%s</option> """ % (choice_item[0], selected, choice_item[1])
320             selected = ""
321 
322     if type(field_obj).__name__ in "ForeignKey":
323         for choice_item in field_obj.get_choices()[1:]:
324             if admin_obj.filter_condtions.get(filter_column)== str(choice_item[0]):  # 就是选择的这个条件,整数转字符串
325                 selected = "selected"
326             select_ele += """<option value="%s" %s>%s</option> """ % (choice_item[0], selected, choice_item[1])
327             selected=''
328 
329     if type(field_obj).__name__ in ['DateTimeField', 'DateField']:  # 如果是时间格式
330         date_els = []  # 日期条件项
331         today_ele = datetime.now().date()  # 今天日期
332         date_els.append(['今天', today_ele])  # 今天
333         date_els.append(['昨天', today_ele - timedelta(days=1)])  # 昨天
334         date_els.append(['近7天', today_ele - timedelta(days=7)])  # 一周
335         date_els.append(['近30天', today_ele - timedelta(days=30)])  # 三十
336         date_els.append(['本月', today_ele.replace(day=1)])  # 本月
337         date_els.append(['近90天', today_ele - timedelta(days=90)])  # 90天
338         date_els.append(['近365天', today_ele - timedelta(days=365)])  # 365天
339         date_els.append(['本年', today_ele.replace(month=1, day=1)])  ##今年
340 
341         for choice_item in date_els:
342             if admin_obj.filter_condtions.get("%s__gte" %filter_column)==str(choice_item[1]):
343                 selected = 'selected'
344             select_ele += """<option value="%s" %s>%s</option> """ % (choice_item[1], selected, choice_item[0])
345             selected = ''
346         filter_column_name = "%s__gte" %filter_column
347     else:
348         filter_column_name = filter_column
349 
350     select_ele += "</select>"
351     select_ele=select_ele.format(filter_column=filter_column_name)#格式化时间的判断条件
352     return mark_safe(select_ele)
353 # ————————16PerfectCRM实现King_admin日期过滤————————
354 
355 # ————————17PerfectCRM实现King_admin单列排序————————
356 # kingadmin排序功能
357 @register.simple_tag
358 def  get_orderby_key(request,column):
359     current_order_by_key = request.GET.get("_o")
360     # ————————18PerfectCRM实现King_admin搜索关键字————————
361     search_key = request.GET.get("_q")
362     if search_key != None:
363         if current_order_by_key != None: #如果不为空  #肯定有某列被排序了
364             if current_order_by_key ==  column: # 判断是否相等 #当前这列正在被排序
365                 if column.startswith("-"): #startsWith是String类中的一个方法,用来检测某字符串是否以另一个字符串开始,返回值为boolean类型
366                     return column.strip("-") #strip去掉  文本中句子开头与结尾的符号的
367                 else:
368                     return "-%s&_q=%s" % (column, search_key)
369         return "%s&_q=%s" % (column, search_key)
370     else:
371     # ————————18PerfectCRM实现King_admin搜索关键字————————
372         if current_order_by_key != None: #如果不为空  #肯定有某列被排序了
373             if current_order_by_key ==  column: # 判断是否相等 #当前这列正在被排序
374                 if column.startswith("-"): #startsWith是String类中的一个方法,用来检测某字符串是否以另一个字符串开始,返回值为boolean类型
375                     return column.strip("-") #strip去掉  文本中句子开头与结尾的符号的
376                 else:
377                     return "-%s"%column
378         #     else:
379         #         return column
380         # else:
381         #     return column
382         return column   #同上4句
383 # kingadmin排序功能
384 
385 # kingadmin排序功能  显示排序图标
386 # @register.simple_tag
387 # def display_order_by_icon(request, column):
388 #     current_order_by_key = request.GET.get("_o")
389 #     if current_order_by_key != None: #肯定有某列被排序了
390 #         if current_order_by_key.strip("-") == column: ## 当前这列正在被排序
391 #             if current_order_by_key.startswith("-"):
392 #                 icon = "fa-arrow-up"
393 #             else:
394 #                 icon = "fa-arrow-down"
395 #             ele = """<i class="fa %s" aria-hidden="true"></i>""" % icon
396 #             return mark_safe(ele)
397 #     return ''
398 # kingadmin排序功能  显示排序图标
399 @register.simple_tag
400 def display_order_by_icon(request, column):
401     current_order_by_key = request.GET.get("_o")
402     if current_order_by_key != None: #肯定有某列被排序了
403         if current_order_by_key.strip("-") == column: # 当前这列正在被排序  #strip去掉  文本中句子开头与结尾的符号的
404             if current_order_by_key.startswith("-"): #startsWith是String类中的一个方法,用来检测某字符串是否以另一个字符串开始,返回值为boolean类型
405                 icon = ""
406             else:
407                 icon = ""
408             ele = """<i style='color: red'>%s</i>""" % icon
409             return mark_safe(ele)
410     return '' #防止出现 None
411 # kingadmin排序功能  显示排序图标
412 
413 # kingadmin排序功能  # 过滤后排序功能 #}
414 @register.simple_tag
415 def get_current_orderby_key(request): #注意生成的URL问题
416     #获取当前正在排序的字段名   #<input type="hidden" name="_o" value="{% get_current_orderby_key request %}">
417     current_order_by_key = request.GET.get("_o")
418     return current_order_by_key or ''
419 # kingadmin排序功能  # 过滤后排序功能 #}
420 
421 # kingadmin排序功能   # 过滤后排序功能 # 排序分页
422 @register.simple_tag
423 def generate_order_by_url (request):
424     current_order_by_key = request.GET.get("_o")
425     if current_order_by_key != None:  # 肯定有某列被排序了
426         return "&_o=%s" % current_order_by_key
427     return ''
428 # kingadmin排序功能   # 过滤后排序功能 # 排序分页
429 # ————————17PerfectCRM实现King_admin单列排序————————
430 
431 # ————————18PerfectCRM实现King_admin搜索关键字————————
432 @register.simple_tag
433 def get_search_key(request):   #  搜索框里保留搜索值
434     search_key = request.GET.get("_q")
435     return search_key or ''
436 # ————————18PerfectCRM实现King_admin搜索关键字————————
437 
438 # ————————23PerfectCRM实现King_admin数据删除————————
439 # <-------------------获取删除映射关系--------------------------------
440 @register.simple_tag
441 def display_all_related_obj(objs):
442     # 取出对象及所有相关联的数据
443     from django.db.models.query import QuerySet
444     if type(objs) != QuerySet:
445         objs = [objs, ]
446     if objs:
447         model_class = objs[0]._meta.model  # 取表对象
448         model_name = objs[0]._meta.model_name  # 取表名
449         return mark_safe(recursive_related_objs_lookup(objs))
450 # <-----------------递归获取映射关系--------------------------------
451 def recursive_related_objs_lookup(objs, name=None, conn_batch_size=0):
452     name = set()
453     print(name)
454     print('传递过来的objs:', objs)
455     # 开始标签的拼接
456     ul_ele = "<ul style='color: blue'>"
457     for obj in objs:
458         li_ele = '''<li>{0}:{1}</li>'''.format(obj._meta.verbose_name, obj.__str__().strip("<>"))
459         print('str:', obj.__str__(), '类型:', type(obj.__str__()))
460         print('关联的表的自定表名:', li_ele)
461         ul_ele += li_ele
462         print('拼接li_ele:', ul_ele)
463         # 映射关系处理
464         # <---------------------------特殊关联处理-----------------------------------
465         # 多对多关系
466         for m2m_field in obj._meta.local_many_to_many:  # local_many_to_many返回列表,many_to_many返回元祖
467             print('--开始循环反射-多对多-关系处理--')
468             sub_ul_ele = "<ul style='color: red'>"
469             m2m_field_obj = getattr(obj, m2m_field.name)  # 反射 如果有选项
470             print('反射选项:', m2m_field_obj)
471 
472             for m2m_data in m2m_field_obj.select_related():
473                 print('开始循环多对多标签拼接:', m2m_data)
474 
475                 sub_li_ele = '''<li>{0}:{1}</li>'''.format(m2m_field.verbose_name, m2m_data.__str__().strip("<>"))
476                 sub_ul_ele += sub_li_ele
477             sub_ul_ele += '</ul>'
478             ul_ele += sub_ul_ele
479             print('生成完整 多对多 标签..:', ul_ele)
480         # <---------------------------外健关联处理------------------------------------
481         for related_obj in obj._meta.related_objects:
482             print('--开始-外健关联-处理--')
483             if hasattr(obj, related_obj.get_accessor_name()):
484                 print('--判断对象中是否包含反查属性--')
485                 accessor_obj = getattr(obj, related_obj.get_accessor_name())
486                 print('获取反查对应的对象: ')
487                 if hasattr(accessor_obj, 'select_related'):
488                     print('--判断有没有获取数据的方法或属性-- ')
489                     target_object = accessor_obj.select_related()
490                     print('获取数据的方法或属性: ', target_object)
491 
492                     if 'ManyToManyRel' in related_obj.__repr__():
493                         print('--开始-外健关联-多对多-处理--.')
494 
495                         # 生成UL
496                         sub_ul_ele = '<ul style="color: green">'
497                         for data in target_object:
498                             print('开始循环-外健关联-标签拼接...', data)
499                             sub_li_ele = '''<li>{0}:{1}</li>'''.format(data._meta.verbose_name,
500                                                                        data.__str__().strip("<>"))
501                             sub_ul_ele += sub_li_ele
502                         sub_ul_ele += '</ul>'
503                         ul_ele += sub_ul_ele
504                         print('-外健关联-生成完整标签:', ul_ele)
505                     # <---------------递归处理-------------------
506                     if len(target_object) != conn_batch_size:
507                         print('--有下级对象存在,进行-递归-循环--')
508                         names = target_object.__str__()
509                         print(names, type(names))
510                         if names == name:
511                             print('--如果是自己关联自己,就不递归了--')
512                             ul_ele += '</ul>'
513                             return ul_ele
514                         else:
515                             print('--防止无限递归+1--')
516                             conn_batch_size = conn_batch_size + 1
517                             node = recursive_related_objs_lookup(target_object, name=names,
518                                                                  conn_batch_size=conn_batch_size)
519                             ul_ele += node
520 
521                     # <---------------由于使用递归,下面的标签样会发生重复,就不需要使用了--------------------
522                 else:
523                     print('外健关联 一对一:', accessor_obj)
524                     target_object = accessor_obj
525                     print("外健关联 一对一:", target_object, '属性:', type(target_object))
526 
527     ul_ele += '</ul>'
528     return ul_ele
529 
530 # ————————23PerfectCRM实现King_admin数据删除————————
531 
532 
533 # ————————24PerfectCRM实现King_admin自定义操作数据————————
534 #自定制 actions功能 显示
535 @register.simple_tag
536 def get_admin_actions(admin_obj):
537     #选择功能
538     options = "<option class='form-control' value='-1'>-------</option>"#默认为空
539     actions = admin_obj.default_actions + admin_obj.actions #默认加自定制
540     print('默认加自定制',actions)
541     for action in actions:
542         action_func = getattr(admin_obj,action)#功能方法  #反射
543         if hasattr(action_func,"short_description"):#反射 如有自定义的名称执行函数方法
544             action_name = action_func.short_description#等于自定义的名称 #显示中文
545         else:
546             action_name = action#等于函数名称
547         options += """<option value="{action_func_name}">{action_name}</option> """.format(action_func_name=action,                                                                                                                                                                                     action_name=action_name)
548     return mark_safe(options)
549 # ————————24PerfectCRM实现King_admin自定义操作数据————————
550 
551 
552 
553 # ————————27PerfectCRM实现King_admin编辑复选框————————
554 # 复选 框内容待选数据
555 @register.simple_tag
556 def get_m2m_available_objs(admin_obj, field_name):
557     '''返回m2m左侧所有待选数据'''
558     # c= admin_obj.model.tags.rel.model.objects.all()
559     # print('c',c)
560     # m2m_objs= admin_obj.model.tags.rel.model.objects.all()
561     # print('m2m_objs',m2m_objs)
562     m2m_model = getattr(admin_obj.model, field_name).rel  # 复选框对象
563     m2m_objs = m2m_model.model.objects.all()  # 获取到复选框所有内容
564     return m2m_objs
565 
566 
567 # 复选 框内容已选中数据
568 @register.simple_tag
569 def get_m2m_chosen_objs(admin_obj, field_name, obj):
570     """
571     返回已选中的列表
572     :param admin_obj:
573     :param field_name:
574     :param obj: 数据对象
575     :return:
576     """
577     # print(["--->obj",obj])
578     if obj.id:
579         return getattr(obj, field_name).all()  # 返回所有的内容
580     return []  # 没有数据为返回空   创建新的记录使用
581 # ————————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中利用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             </tr>
149           </thead>
150 
151         {## ————————09PerfectCRM实现King_admin显示注册表的内容————————#}
152 
153           {## ————————59PerfectCRM实现king_admin行内编辑————————#}
154 {#          <tbody>#}
155           <tbody id="model_table_data">
156           {## ————————59PerfectCRM实现king_admin行内编辑————————#}
157 
158             {#循环调用kingadmin/views 里的def table_data_list下的admin_obj.querysets #}
159             {% for obj in admin_obj.querysets %}
160                 <tr>
161                     {## ————————24PerfectCRM实现King_admin自定义操作数据————————#}
162                     <td><input tag="obj_checkbox" type="checkbox" value="{{ obj.id }}"> </td>
163                     {## ————————24PerfectCRM实现King_admin自定义操作数据————————#}
164 
165                     {#通过kingadmin_tags在后台处理 再传到前端 #}
166                     {#调用kingadmin/templateags/kingadmin_tags 里的def build_table_row(admin_obj,obj):#}
167                     {## ————————19PerfectCRM实现King_admin数据修改————————#}
168                     {% build_table_row  admin_obj obj  %}{# kingadmin动态生成model编辑 #}
169                     {## ————————19PerfectCRM实现King_admin数据修改————————#}
170 
171                 </tr>
172             {% endfor %}
173           </tbody>
174         {## ————————09PerfectCRM实现King_admin显示注册表的内容————————#}
175     </table>
176 
177      {## ————————24PerfectCRM实现King_admin自定义操作数据————————#}
178     <div class="radio">
179         数据总量:  {{ admin_obj.querysets.paginator.count }}  条
180     </div>
181      {## ————————24PerfectCRM实现King_admin自定义操作数据————————#}
182 
183 
184     {## ————————12PerfectCRM实现King_admin分页上下页————————#}
185 {#    <div class="row">#}
186 {#        <div class="pagination">#}
187 {#            <span class="step-links">#}
188 {#                {% if admin_obj.querysets.has_previous  %}#}
189 {##}
190                     {## ————————15PerfectCRM实现King_admin多条件过滤————————#}
191 {#                     <a href="?page={{ admin_obj.querysets.previous_page_number }}#}
192 {#                   <a href="?page={{ admin_obj.querysets.previous_page_number }}{%  generate_filter_url admin_obj %}">上一页 </a>#}
193                      {## ————————15PerfectCRM实现King_admin多条件过滤————————#}
194 {##}
195 {#                {% endif %}#}
196 {##}
197 {#                <span class="current">#}
198 {#                    第{{ admin_obj.querysets.number }}页,共{{ admin_obj.querysets.paginator.num_pages }}页#}
199 {#                </span>#}
200 {##}
201 {#                {% if admin_obj.querysets.has_next %}#}
202 {##}
203                     {## ————————15PerfectCRM实现King_admin多条件过滤————————#}
204 {#                    <a href="?page={{ admin_obj.querysets.next_page_number }}#}
205 {#                    <a href="?page={{ admin_obj.querysets.next_page_number }}{%  generate_filter_url admin_obj %}">下一页</a>#}
206                        {## ————————15PerfectCRM实现King_admin多条件过滤————————#}
207 {##}
208 {#                {% endif %}#}
209 {#            </span>#}
210 {#        </div>#}
211 {#    </div>#}
212     {## ————————12PerfectCRM实现King_admin分页上下页————————#}
213 
214 {## ————————13PerfectCRM实现King_admin分页页数————————#}
215 {#    <nav aria-label="...">#}
216 {#      <ul class="pagination">#}
217 {#        <li class="disabled"></li>#}
218 {#          {% for  page in admin_obj.querysets.paginator.page_range  %}  {#循环 分页 范围#}
219 {##}
220 {#              {% if page == admin_obj.querysets.number  %} {#当前页高亮,否则不加高亮#}
221 {#                  <li class="active">#}
222 {#              {% else %}#}
223 {#                   <li >#}
224 {#              {% endif %}#}
225 {##}
226                                         {#后台拼接返回,kingadmin/templatetags/kingadmin_tags.py 里def generate_filter_url(admin_obj):#}
227 {#              <a href="?page={{ page }}{%  generate_filter_url admin_obj %}">{{ page }}</a>#}
228 {#              </li>#}
229 {#          {% endfor %}#}
230 {#      </ul>#}
231 {#    </nav>#}
232 {## ————————13PerfectCRM实现King_admin分页页数————————#}
233 
234 {## ————————14PerfectCRM实现King_admin分页的省略显示————————#}
235 
236     <div class="row panel-body">
237         <nav aria-label="...">
238             <ul class="pagination">
239                 <!--如果有上一页-->
240                 {% if admin_obj.querysets.has_previous %}
241                      {## ————————18PerfectCRM实现King_admin搜索关键字————————#}
242                     {## ————————17PerfectCRM实现King_admin单列排序————————#}
243 {#                    <li><a href="?page={{ admin_obj.querysets.previous_page_number }}{% generate_filter_url admin_obj %}"#}
244 {#                           aria-label="Previous"><span aria-hidden="true">&laquo;</span></a></li>#}
245 
246                             {#获取上一个数字#}                         {# kingadmin排序功能 # 过滤后排序功能#排序#}           {#分页#}
247 {#<li><a href="?page={{ admin_obj.querysets.previous_page_number }}{% generate_order_by_url request  %}{% generate_filter_url admin_obj %}"#}
248 {#       aria-label="Previous"><span aria-hidden="true">上页</span></a></li>#}
249                      {## ————————17PerfectCRM实现King_admin单列排序————————#}
250                     <li><a href="?page={{ admin_obj.querysets.previous_page_number }}
251 {% generate_order_by_url request  %}{% generate_filter_url admin_obj %}&_q={% get_search_key request %}"
252                            aria-label="Previous"><span aria-hidden="true">上页</span></a></li>
253                      {## ————————18PerfectCRM实现King_admin搜索关键字————————#}
254                 {% else %}
255                     <li class="disabled">
256                         <a href="#" aria-label="Previous"><span aria-hidden="true">&laquo;</span></a></li>
257                 {% endif %}
258                 <!--#分页的省略显示  kingadmin/templatetags/kingadmin_tags.py里def pag_omit(request,admin_obj):-->
259                 {% pag_omit request admin_obj %}
260                 <!--如果有下一页-->
261                 {% if admin_obj.querysets.has_next %}
262                  {## ————————18PerfectCRM实现King_admin搜索关键字————————#}
263                  {## ————————17PerfectCRM实现King_admin单列排序————————#}
264 {#                    <li><a href="?page={{ admin_obj.querysets.next_page_number }}{% generate_filter_url admin_obj %}"#}
265 {#                           aria-label="Previous"><span aria-hidden="true">&raquo;</span></a></li>#}
266 
267 {#<li><a href="?page={{ admin_obj.querysets.next_page_number }}{% generate_order_by_url request  %}{% generate_filter_url admin_obj %}"#}
268 {#       aria-label="Previous"><span aria-hidden="true">下页</span></a></li>#}
269                  {## ————————17PerfectCRM实现King_admin单列排序————————#}
270                     <li><a href="?page={{ admin_obj.querysets.next_page_number }}
271 {% generate_order_by_url request  %}{% generate_filter_url admin_obj %}&_q={% get_search_key request %}"
272                            aria-label="Previous"><span aria-hidden="true">下页</span></a></li>
273                 {## ————————18PerfectCRM实现King_admin搜索关键字————————#}
274 
275                 {% else %}
276                     <li class="disabled"><a href="#" aria-label="Previous"><span aria-hidden="true">&raquo;</span></a>
277                     </li>
278                 {% endif %}
279             </ul>
280         </nav>
281     </div>
282 {## ————————14PerfectCRM实现King_admin分页的省略显示————————#}
283 
284 {## ————————59PerfectCRM实现king_admin行内编辑————————#}
285 {% if admin_obj.list_editable %}
286     <div>
287         <form method="post" onsubmit="return PrepareFormData(this)">{% csrf_token %}
288             <button class="btn btn-info pull-right">保存</button>
289         </form>
290     </div>
291 {% endif %}
292 {## ————————59PerfectCRM实现king_admin行内编辑————————#}
293 
294 {% endblock %}
295 {## ————————08PerfectCRM实现King_admin显示注册表的字段表头————————#}
296 
297 {## ————————59PerfectCRM实现king_admin行内编辑————————#}
298 {% block js %}
299 <script>
300     $(document).ready(function () {
301         $('input[type="checkbox"][data-tag="editable"]').change(function() {
302              if(this.checked) {
303                  // do something when checked
304                  console.log("checked...")
305                  $(this).val("True")
306 
307              }else {
308                  console.log("unchekc")
309                   $(this).val("False")
310              }
311         });
312     });//end doc ready
313     function PrepareFormData(form_ele) {
314         var form_data = [];
315         $("#model_table_data tr").each(function () {
316             var obj_id = $(this).children().first().find("input").val();
317 
318             console.log(obj_id);
319             if (obj_id){ //table obj row
320                 var row_data = {};//all columns need to be updated
321                 $(this).find("[data-tag='editable']").each(function () {
322                     //console.log($(this).attr("name") + "----" +$(this).val())
323                     row_data[$(this).attr("name")] = $(this).val();
324                 });//end find each
325                 row_data['id'] = obj_id;
326 
327                 form_data.push(row_data);
328             }
329 
330         });//end each
331         console.log(form_data)
332         var ele = '<input type="hidden" name="editable_data" value=' + JSON.stringify(form_data) + ' >';
333         $(form_ele).append(ele);
334 
335         return true;
336     }
337 </script>
338 {% endblock %}
339 {## ————————59PerfectCRM实现king_admin行内编辑————————#}
{#table_data_list.html#}

 1 {#king_base.html#}
 2 {## ————————02PerfectCRM创建ADMIN页面————————#}
 3 {#模板文件  king_base.html#}
 4 <!DOCTYPE html>
 5 <html lang="zh-CN">
 6     <head>
 7 {#      <meta> 元素可提供有关页面的元信息(meta-information),比如针对搜索引擎和更新频度的描述和关键词。#}
 8 {#      <meta> 标签位于文档的头部,不包含任何内容。<meta> 标签的属性定义了与文档相关联的名称/值对。#}
 9         <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
10         <meta http-equiv="X-UA-Compatible" content="IE=edge">
11         <meta name="viewport" content="width=device-width, initial-scale=1">
12         <meta name="description" content="">
13         <meta name="author" content="">
14 
15         <link rel="icon" href="/static/king_img/king_logo.jpg">{# icon,指的是图标 #}
16         <title>KingAdmin</title> {# 页面头部显示#}
17 
18 {#        使用link来调用外部的css文件#}
19         <link rel="stylesheet"  href="/static/king_css/bootstrap.css"  /> {#导航栏样式#}
20         <link rel="stylesheet"  href="/static/king_css/dashboard.css" /> {#指示板样式#}
21 
22         {## ————————27PerfectCRM实现King_admin编辑复选框————————#}
23         <link rel="stylesheet"  href="/static/king_css/king_admin_change.css" /> {#编辑复选框样式#}
24         {## ————————27PerfectCRM实现King_admin编辑复选框————————#}
25 
26     </head>
27 
28     <body>
29 
30         {% block body %}{#自定义内容 body#}{% endblock %}
31 
32 {#        将纯JavaScript的语句另外保存在一个"*.js"的文件中,需要时再调用。#}
33         <script src="/static/king_js/jquery.js"></script>   {# jQuery 是一个 JavaScript库,极大地简化了 JavaScript 编程。#}
34         <script src="/static/king_js/bootstrap.js"></script>  {#指示板JS事件#}
35 
36         {## ————————24PerfectCRM实现King_admin自定义操作数据————————#}
37         <script src="/static/king_js/king_admin_js.js"></script>  {#自定义JS事件#}
38         {## ————————24PerfectCRM实现King_admin自定义操作数据————————#}
39         
40         {## ————————27PerfectCRM实现King_admin编辑复选框————————#}
41         <script src="/static/king_js/king_admin_change.js"></script>  {#编辑复选框JS事件#}
42         {## ————————27PerfectCRM实现King_admin编辑复选框————————#}
43 
44         {## ————————59PerfectCRM实现king_admin行内编辑————————#}
45         {% block js %}{# 独立的JS#}{% endblock %}
46         {## ————————59PerfectCRM实现king_admin行内编辑————————#}
47 
48     </body>
49 </html>
50 
51 {## ————————02PerfectCRM创建ADMIN页面————————#}
{#king_base.html#}


 

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

原文地址:https://www.cnblogs.com/ujq3/p/8987169.html