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注册功能————————
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)#循环打印 配置文件.设置.安装应用程序#.Perfectcustomer\settings里的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()默认删除空白符(包括'\n', '\r', '\t', ' ') 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添加用户时密码加密————————
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("\033[41;1mrun form defautl clean method...\033[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行内编辑————————
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编辑复选框————————
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">«</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">«</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">»</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">»</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行内编辑————————#}
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页面————————#}
如果感觉本章博客对您有帮助,请尽情打赏吧!
您的资助是我最大的动力!
金额随意,欢迎来赏!
如果,您希望更容易地发现我的新博客,不妨点击一下绿色通道的
因为,我的写作热情也离不开您的肯定支持,感谢您的阅读,我是【颜言】!