zoukankan      html  css  js  c++  java
  • 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#}


     

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

  • 相关阅读:
    Android 禁止软键盘自动弹出
    Android之Adapter用法总结
    如何成为android高手
    最强大的文案策略
    外贸电商的ERP有很多
    ERP行业销售如何挖掘潜在客户?
    新制造
    C#实现字符串相似度算法
    cmd
    对于大型公司项目平台选择j2ee的几层认识
  • 原文地址:https://www.cnblogs.com/ujq3/p/8987169.html
Copyright © 2011-2022 走看看