zoukankan      html  css  js  c++  java
  • 西游之路——python全栈——CRM项目之Kingadmin开发

    一、Kingadmin设计

      1、原因

        由于每个用户都需要增删改查,所有开发一个Kingadmin模块,支持所有用户,只需配置注册即可

      2、创建APP之Kingadmin,并把statics、templates及相关的views跟urls导入致Kingadmin

    二、自动发现及注册功能开发

      1、程序启动则自动触发注册

        流程:  程序启动    ==>   解析views视图   ==>   调用app_setup模块下kingadmin_auto_discover函数   ==>   逐一触发其app下的Kingadmin模块   ==>   调用sites模块实例化后创建一个字典(只实例化一次),再执行register函数进行注册动作,并把信息封装到字典

    ==========================

    1 from kingadmin import app_setup
    2 app_setup.kingadmin_auto_discover()
    解析views视图

    ==========================

    1 from django import conf   # 动态获取settings配置
    2 
    3 def kingadmin_auto_discover():
    4     for app_name in conf.settings.INSTALLED_APPS:
    5         try:
    6             mod = __import__('%s.kingadmin' % app_name)
    7             print(mod.kingadmin)
    8         except ModuleNotFoundError:
    9             pass
    app_setup下kingadmin_auto_discove函数

    ==========================

     1 from crm import models
     2 from kingadmin.sites import site
     3 from kingadmin.admin_base import BaseKingAdmin
     4 
     5 class CustomAdmin(BaseKingAdmin):
     6     list_display = ['name', 'source', 'contact_type', 'contact', 'consultant', 'consult_content', 'status', 'date']
     7     list_filter = ['source', 'consultant', 'status', 'date']
     8 
     9 site.register(models.CustomerInfo,CustomAdmin)
    10 site.register(models.Menus)
    11 site.register(models.UserProFile)
    12 site.register(models.StudyRecord)
    13 site.register(models.CustomerFollowUp)
    逐一触发其app下的Kingadmin模块(其中一个)

    =========================

     1 from kingadmin.admin_base import BaseKingAdmin
     2 
     3 class AdminSite(object):
     4     def __init__(self):
     5         self.enabled_admins = {}
     6 
     7     def register(self,model_class,admin_class=None):
     8         """注册admin表"""
     9         # 根据model中类名获取APP名
    10         app_name = model_class._meta.app_label
    11         # 根据model中类名获取表名,类名的小写
    12         model_name = model_class._meta.model_name
    13 
    14         # 不传值时默认BaseKingAdmin,并实例化
    15         if not admin_class:
    16             admin_class = BaseKingAdmin()
    17         else:
    18             # 每次实例化,防止使用同一内存地址
    19             admin_class = admin_class()
    20         # ??????? admin_class为对象才能 .model添加存入对象
    21         admin_class.model = model_class  # 把model_class赋值给admin_class为了能关联起来
    22         if app_name not in self.enabled_admins:
    23             self.enabled_admins[app_name] = {}
    24         self.enabled_admins[app_name][model_name] = admin_class
    25 
    26         print(model_class,admin_class)
    27 
    28 site = AdminSite()   # 只实例化一次,后面的导入为调用对象
    行register函数进行注册动作,并封装

    ========================

    1 dict = {
    2     'app1':{'表名1':'自定义类名1','表名2':'自定义类名2'},
    3     'app2':{'表名1':'自定义类名1','表名2':'自定义类名2'},
    4 }
    字典结构

    三、APP首页开发

      1、URL

    re_path('^kingadmin/', include('kingadmin.urls')),
    
    
    urlpatterns = [
        re_path('^$', views.app_index,name='app_index'),
        re_path('^/(w+)/(w+)/$', views.table_obj_list,name='table_obj_list'),
        re_path('^login/', views.acc_login),
        re_path('^logout/', views.acc_logout,name='logout'),
    ]
    

      2、视图函数

    1 def app_index(request):
    2     return render(request, 'kingadmin/app_index.html',{'site':site})
    Kingadmin/views.py

      3、setting配置与templates模块

    注意:从上往下找

      

      4、templates模块

     1 {% extends 'kingadmin/index.html' %}
     2 
     3 {% block right-content-container %}
     4     <h1 class="page-header">app</h1>
     5 
     6     <div>
     7         {% for app_name,app_tables in site.enabled_admins.items %}
     8         <table class="table table-striped">
     9             <thead>
    10                 <tr>
    11                     <th>{{app_name}}</th>
    12                 </tr>
    13             </thead>
    14             <tbody>
    15                 {% for model_name in app_tables %}
    16                 <tr>
    17                     <td><a href="{% url 'table_obj_list' app_name model_name %}">{{model_name}}</a></td>
    18                     <td>ADD</td>
    19                     <td>Change</td>
    20                 </tr>
    21                 {% endfor %}
    22             </tbody>
    23         </table>
    24         {% endfor %}
    25     </div>
    26 
    27 {% endblock %}
    app_index.html

    四、model_obj_list开发之生成列表跟过滤

      1、URL

        见上

      2、views视图

     1 def get_filter_result(admin_class,request):
     2     filter_conditions = {}
     3     for key,val in request.GET.items():
     4         # val为空时不过滤
     5         if val:
     6             filter_conditions[key] = val
     7     filtered_querysets = admin_class.model.objects.filter(**filter_conditions).all()
     8     return filtered_querysets,filter_conditions
     9 
    10 @login_required()
    11 def table_obj_list(request,app_name,model_name):
    12     """取出指定model里的数据返回给前端"""
    13     admin_class = site.enabled_admins[app_name][model_name]
    14 
    15     # 调用函数过滤处理,并返回
    16     querysets,filter_conditions = get_filter_result(admin_class, request)
    17     admin_class.filter_conditions = filter_conditions
    18 
    19     return render(request, 'kingadmin/table_obj_list.html',{
    20         'querysets':querysets,
    21         'admin_class':admin_class,
    22     })
    Kingadmin/views.py

      3、templates模块

     1 {% extends 'kingadmin/index.html' %}
     2 {# 导入标签模块 #}
     3 {% load kingadmin_tag %}  {# build_table_row' is not a registered tag library 重启即可 #}
     4 
     5 {% block right-content-container %}
     6     <h1 class="page-header">app</h1>
     7 
     8     <div>
     9         <form action="">
    10             {% for filter_column in admin_class.list_filter %}
    11                 {% build_filter_ele filter_column admin_class %}
    12             {% endfor %}
    13             <input type="submit" value="过滤">
    14         </form>
    15     </div>
    16 
    17     <div>
    18         <table class="table table-striped">
    19             <thead>
    20                 <tr>
    21                     {% for column in admin_class.list_display %}
    22                     <th>{{column}}</th>
    23                     {% endfor %}
    24                 </tr>
    25             </thead>
    26             <tbody>
    27                 {% for obj in querysets %}
    28                 <tr>{% build_table_row obj admin_class %}</tr>
    29                 {% endfor %}
    30             </tbody>
    31         </table>
    32 
    33     </div>
    34 
    35 {% endblock %}
    tables_obj_list.html

      4、templatetags自定义

     1 from django.template import Library
     2 from django.utils.safestring import mark_safe
     3 import datetime
     4 
     5 register = Library()
     6 
     7 @register.simple_tag
     8 def build_table_row(obj,admin_class):
     9     """生成一条记录html element"""
    10     ele = ''
    11     for column_name in admin_class.list_display:
    12         column_obj = admin_class.model._meta.get_field(column_name)
    13         if column_obj.choices:  # 判断字段是否为choice
    14             column_data = getattr(obj, 'get_%s_display' %column_name)()   # 获取choice的值
    15         else:
    16             column_data = getattr(obj, column_name)  # 反射
    17         ele += '<td>%s</td>' % column_data
    18     return mark_safe(ele)
    19 
    20 @register.simple_tag
    21 def build_filter_ele(filter_column,admin_class):
    22     """过滤"""
    23     #获取字段对象
    24     column_obj = admin_class.model._meta.get_field(filter_column)
    25     try:
    26         filter_select = '<select name=%s>' % filter_column
    27         for choice in column_obj.get_choices():
    28             selected = ''
    29             # if filter_column in admin_class.filter_conditions:  # 当前字段被过滤了
    30             if str(choice[0]) == admin_class.filter_conditions.get(filter_column):  # 当前值被选中
    31                 selected = 'selected'
    32             option = "<option value='%s' %s>%s</option>" % (choice[0],selected,choice[1])
    33             filter_select += option
    34     except AttributeError as e:
    35         print('err',e)
    36         filter_select = '<select name=%s__gte>' % filter_column
    37         # 判断字段属性
    38         if column_obj.get_internal_type() in ('DateField','DateTimeField'):
    39             time_obj = datetime.datetime.now()
    40             time_list = [
    41                 ['--------------',''],
    42                 ['Today',time_obj],
    43                 ['Past 7 day',time_obj-datetime.timedelta(7)],
    44                 ['This month',time_obj.replace(day=1)],
    45                 ['Past 3 month',time_obj-datetime.timedelta(90)],
    46                 ['This year',time_obj.replace(month=1,day=1)],
    47                 ['Any day',''],
    48             ]
    49             for i in time_list:
    50                 selected = ''
    51                 time_to_str = '' if not i[1] else '%s-%s-%s' %(i[1].year,i[1].month,i[1].day)
    52                 if time_to_str == admin_class.filter_conditions.get('%s__gte' %filter_column):  # 当前值被选中
    53                     selected = 'selected'
    54                 option = '<option value=%s %s>%s</option>' % (time_to_str,selected,i[0])
    55                 filter_select += option
    56 
    57     filter_select += '</select>'
    58     return mark_safe(filter_select)
    kingadmin_tag.py
  • 相关阅读:
    Python_Excel文件操作
    Python_CRC32
    Python_替换当前目录下文件类型
    Python_os、os.path、os.shutil使用案例
    Python_文件与文件夹操作
    MyBatis/Ibatis中#和$的区别
    遍历listmap 遍历map
    jquery操作select(取值,设置选中)
    ==与===区别(两个等号与三个等号)
    常用map总结
  • 原文地址:https://www.cnblogs.com/Lujun1028/p/9833403.html
Copyright © 2011-2022 走看看