#################################### kingadmin ###################################### # 需要做到的效果:点击客户库,出现所有客户信息,以及增删改查|多条件过滤|搜索|排序等功能; # 后台添加相应数量的客户; # 给admin中客户信息显示样式做自定制,包括过滤等; # admin.py class CustomerAdmin(admin.ModelAdmin): list_display = [‘name‘,‘source‘,‘contact_type‘,‘contact‘,‘consultant‘,‘consult_content‘,‘status‘,‘date‘] list_filter = [‘source‘,‘consultant‘,‘status‘,‘date‘] search_filed = [‘contact‘,‘consultant__name‘] # 这个consultant是外键,搜索其字段需要双下划线‘__name‘; # 注册 admin.site.register(models.CustomerInfo,CustomerAdmin) # 显示样式大概如下: # 因为我们做的是插拔式kingadmin,所以创建独立的app python3 manage.py startapp kingadmin ‘kingadmin‘ # 需要独立的static以及template STATICFILES_DIRS = [ os.path.join(BASE_DIR, ‘statics‘), os.path.join(BASE_DIR, ‘kingadmin/statics‘), ] TEMPLATES = [ ... ‘DIRS‘:[ os.path.join(BASE_DIR, ‘templates‘), os.path.join(BASE_DIR, ‘kingadmin/templates‘) ], ... ] # 将crm应用中静态文件以及主模板都拷贝到kingadmin中; # 写kingadmin的视图以及urlconf # urls.py ... url(r‘^kingadmin/‘, include(‘kingadmin.urls‘)) # kingadmin中也创建一个urls.py ... url(r‘^login/‘, views.user_login), url(r‘^logout/‘, views.user_logout, name=‘logout‘), # 写一个独立的用户登录注销,将项目中的拷贝过来做一些修改 from django.shortcuts import render,redirect from django.contrib.auth import authenticate,login,logout def user_login(request): error_message = ‘‘ if request.method == ‘POST‘: username = request.POST.get(‘username‘) password = request.POST.get(‘password‘) user = authenticate(username=username,password=password) if user: login(request,user) return redirect(request.GET.get(‘next‘,‘/kingadmin/‘)) else: error_message = "worng username or password" return render(request, ‘/kingadmin/login.html‘,{‘error_message‘:error_message}) def user_logout(request): logout(request) return redirect(‘/login/‘) # 出现了一个问题,访问的还是项目中的login页面; # 因为配置中的template配置是从上往下找的,从第一个找到login页面就显示了; # 修改kingadmin/login.html中的标题为kingadmin # 措施:在templates中新建一个文件夹存放html页面,并修改login访问路径; # 登录成功之后跳转kingadmin下的首页; # 在kingadmin中创建首页; # urls.py ... url(r‘^$‘,views.app_index,name=‘app_index‘) # views.py def app_index(request): return render(request, ‘/kingadmin/app_index.html‘) # app_index.html {% extends ‘kingadmin/index.html‘ %} {% block right_content %} The content for urself! {% endblock right_content %} # index.html # block在dashboard位置; {% block right_content %} {% endblock right_content %} # 将已经注册的app显示到页面中;怎么判断有没有注册? # 拿到settings.py中的INSTALLED_APPS,先页面中显示; # views.py from PerfectCRM import settings def app_index(request): print(settings.INSTALLED_APPS) return render(request, ‘/kingadmin/app_index.html‘) # 问题:如果将kingadmin搬到别的项目中呢?PerfectCRM就读取不到; # 措施:动态导入;django.conf.settings动态获取项目settings配置 # views.py from PerfectCRM import settings from django import conf def app_index(request): print(conf.settings.INSTALLED_APPS) return render(request, ‘/kingadmin/app_index.html‘) # 模仿admin.py中自定制显示的操作; # 在crm应用中添加kingadmin.py;完成注册,自定制显示等操作; # 首先,需要让django能够访问到这个文件,拿到里面的配置: # 方法:在视图中,根据conf.settings中的字符串‘crm‘, # 找到这个应用下的kingadmin文件,执行里面的代码; # 知识点:反射; from django import conf def app_index(request): for app_name in conf.settings.INSTALLED_APPS: try: _module = __import__(‘%s.kingadmin‘%app_name) print(_module.kingadmin) except ImportError: pass return render(request, ‘kingadmin/app_index.html‘) # 这样就找到了kingadmin.py # 怎么显示app下的表? # 怎么让django识别admin类下的展示的一些配置?绑定表跟类; enabled_admins = { # 应用名:{‘表名‘:‘admin类‘, ...} ‘crm‘:{‘customer‘: CustomerAdmin, ‘role‘: RoleAdmin} } # 怎么生成这样的字典? # kingadmin.py中大致模样: class CustomerAdmin(object): list_display = [‘name‘,‘source‘,...] list_filter = [‘source‘,‘consultant‘, ...] search_field = [‘contact‘, ...] admin.site.register(models.Customer,CustomerAdmin) # 并且在所有app中都支持这个注册功能 # 再建一个student的应用,并注册,写一个测试model # models.py class Test(models.Model): name = models.CharField(max_length=32) # 再建一个kingadmin.py class TestAdmin(object): list_display=[‘name‘] admin.site.register(models.Test,TestAdmin) # 读取每个app中的kingadmin,最终生成上面的全局字典; # 在kingadmin下新建sites.py # sites.py class AdminSite(object): def __init__(self): self.enabled_admins = {} def register(self,model_class,admin_class=None): """注册admin表""" print(model_class,admin_class) site = AdminSite() # kingadmin.py from crm import models from kingadmin.sites import site class CustomerAdmin(object): pass site.register(models.Customer,CustomerAdmin) # 问题:执行kingadmin.py的操作应该是程序一启动就执行, # 所以,不应该放在app_index()视图中; # 措施:新建app_setup.py将这些操作写入函数放置在这个文件中; # app_setup.py from django import conf def kingadmin_auto_discover(): for app_name in conf.settings.INSTALLED_APPS: try: _module = __import__(‘%s.kingadmin‘%app_name) print(_module.kingadmin) except ImportError: pass # views.py from kingadmin import app_setup app_setup.kingadmin_auto_discover() ... # 怎么通过表名拿到app的名字? # 使用python3 manage.py shell 来做一些模块属性方法的查找 # 因为ipython3中无法进入django数据库环境; >> from crm import models >> models.CustomerInfo # 怎么通过表名拿到app的名字? >> models.CustomerInfo._meta <Options for CustomerInfo> >> dir(models.CustomerInfo._meta) # 将内容复制到txt中,搜app_label >> models.CustomerInfo._meta.app_label ‘crm‘ # 就拿到了应用名 # 构建全局字典时,嵌入应用名时需要判断是否存在; # sites.py class AdminSite(object): def __init__(self): self.enabled_admins = {} def register(self,model_class,admin_class=None): """注册admin表""" print(model_class,admin_class) app_name = model_class._meta.app_label model_name = model_class._meta.model_name # 全局字典中不存在这个应用名,就添加; if app_name not in self.enabled_admins: self.enabled_admins[app_name] = {} # 表名怎么获取? # >> models.CustomerInfo._meta.model_name self.enabled_admin[app_name][model_name] = admin_class # 只实例化一次 site = AdminSite() # 这样就构造一个类似下面的字典 enabled_admins = { # 应用名:{‘表名‘:‘admin类‘, ...} ‘crm‘:{‘customer‘: CustomerAdmin, ‘role‘: RoleAdmin} } # 将字典数据返回前端,返回site就可以了; # views.py def app_index(request): return render(request, ‘kingadmin/app_index.html‘, {‘site‘:site}) # app_index.html {% for app_name,app_tables in site.enabled_admins.items %} {{ app_name }}{{ app_tables }} {% endfor %} >> crm{‘customerinfo‘:<class...>} student{‘test‘:<class...>} # 只要将这些对象输出到表格中;在bootstrap中找表格示例; {% for app_name,app_tables in site.enabled_admins.items %} <table class="table table-striped"> <thead> <tr> <th>{{ app_name }}</th> </tr> </thead> <tbody> {% for model_name in app_tables %} <tr> <td><a href="{% url ‘table_obj_list‘ app_name model_name %}">{{ model_name }}</a></td> <td>ADD</td> <td>Change</td> </tr> {% endfor %} </tbody> </table> # crm中多注册几个表 site.register(models.Role) site.register(models.Menus) site.register(models.UserProfile) ################################ 以上是注册模型类到kingadmin的功能