博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
CRM客户关系管理系统(三)
阅读量:6151 次
发布时间:2019-06-21

本文共 10816 字,大约阅读时间需要 36 分钟。

第四章、kingadmin开发设计

 4.1.kingadmin设计

django admin注册model的写法

crm/admin.py

class CustomerAdmin(admin.ModelAdmin):    #显示    list_display = ['name','source','contact_type','contact','consultant','consult_content','status','date']    #过滤    list_filter = ['source','consultant','status','date']    #搜索,consultant是外键,必须加“__字段名”    search_fields = ['contact','consultant__name']admin.site.register(models.CustomerInfo,CustomerAdmin)

后台显示

这是后台显示的样子,如果我们想让前端也显示类似这样的页面该怎么做呢?这就需要照django自带的admin写法,自己自定义个kingadmin(模仿admin)

 

kingadmin

(1)创建app kingadmin

python manage.py startapp kingadmin

添加到settings的INSTALL_APPS里面

INSTALLED_APPS = [    'django.contrib.admin',    'django.contrib.auth',    'django.contrib.contenttypes',    'django.contrib.sessions',    'django.contrib.messages',    'django.contrib.staticfiles',    'crm',    'kingadmin',]

因为想让kingadmin app以后可以直接移植到其它项目中,所以在kingadmin目录下单独创建templates/kingadmin和static目录,把之前的静态文件和模板拷贝进去

 

(2) settings里面设置kingadmin静态文件和templates路径

STATIC_URL = '/static/'STATICFILES_DIRS = (    os.path.join(BASE_DIR, 'statics'),    os.path.join(BASE_DIR, 'kingadmin/statics'),  )

 

(4)PerfectCRM/url.py添加路由分发

urlpatterns = [    url(r'^kingadmin/', include('kingadmin.urls')),]

 (5)kingamdin/urls.py

# kingadmin/urls.pyfrom django.conf.urls import urlfrom kingadmin import viewsurlpatterns = [    url(r'^login/', views.acc_login,name='login'),    url(r'^logout/', views.acc_logout,name='logout'),]

 

(6)kingamdin/views.py

 登录界面也单独创建

 

 

# kingadmin/views.pyfrom django.shortcuts import render,redirectfrom django.contrib.auth import authenticate,login,logoutdef acc_login(request):    error_msg = ''    if request.method == 'POST':        username = request.POST.get('username',None)        password = request.POST.get('password',None)        #user是一个对象        #验证        user = authenticate(username=username,password=password)        if user:            #登录(已生成session)            login(request, user)            #如果有next值就获取next值,没有就跳转到首页            return redirect(request.GET.get('next','/kingadmin/'))        else:            error_msg = '用户名或密码错误!'    return render(request,'kingadmin/login.html',{
'error_msg':error_msg})def acc_logout(request): logout(request) return redirect("/login/")

 

(7)kingamdin/urls.py

添加登录后跳转到“app_index.html”页面

urlpatterns = [    url(r'^$', views.app_index,name='app_index'),    url(r'^login/', views.acc_login,name='login'),    url(r'^logout/', views.acc_logout,name='logout'),]

(8)kingadmin/views.py

def app_index(request):    return render(request,'kingadmin/app_index.html')

(9)kingadmin/app_index.html

 kingadmin/index.html中添加block right-content-container

king/index.html

 app_index.html

{#templates/kingadmin/app_index.html#}{% extends 'kingadmin/index.html' %}{% block right-content-container %}    {% endblock %}

 

 

4.2.kingadmin自动发现及注册功能开发

 想让app_index.html页面像后台一样显示所有注册的app以及下面的表名

 

 

 

(1)kingadmin/app_setup.py

# kingadmin/app_setup.pyfrom django import confdef kingadmin_auto_discover():    for app_name in conf.settings.INSTALLED_APPS:        try:            #去每个app下面执行kingadmin.py文件            mod = __import__('%s.kingadmin'%app_name)            #打印每个app已注册的model名字            print(mod.kingadmin)        except ImportError:            pass

 

(2)crm/kingadmin.py

# crm/kingadmin.pyfrom kingadmin.sites import sitefrom crm import modelsprint('crm kingadmin....')#注册modelclass CustomerAdmin(object):    list_display = ['name','source','contact_type','contact','consultant','consult_content','status','date']    list_filter = ['source','consultant','status','date']    search_fields = ['contact','consultant__name']site.register(models.CustomerInfo,CustomerAdmin)

(3)student/kingadmin.py

创建app student

student/models.py

# student/models.pyfrom django.db import modelsclass Test(models.Model):    name = models.CharField(max_length=64)

student/kingadmin.py

# student/kingadmin.pyfrom student import modelsfrom kingadmin.sites import siteprint('student kingadmin.....')#注册modelclass TestAdmin(object):    list_display = ['name']site.register(models.Test,TestAdmin)

(4)kingadmin/views.py

# kingadmin/views.pyfrom kingadmin import app_setup#程序一启动就自动执行app_setup.kingadmin_auto_discover()

说明:

程序一启动,会执行每个app下面的kingadmin.py,注册全局的字典

 

from django import conf

conf.settings.INSTALL_APPS

动态获取settings里面所有添加的app名字

 

运行程序

 

(5)返回全局字典

我们想要的字典格式如下:

修改sites.py

# kingadmin/sites.pyclass AdminSite(object):    def __init__(self):        self.enable_admins = {}    #两个参数,一个表名,一个自定义的admin类    def register(self,model_class,admin_class=None):        '''注册admin表'''        # print('register',model_class,admin_class)        #获取app名字        app_name = model_class._meta.app_label        #获取表名        model_name = model_class._meta.model_name        if app_name not in self.enable_admins:            self.enable_admins[app_name] = {}        self.enable_admins[app_name][model_name] = admin_class#实例化,就可以调用register方法site = AdminSite()

kingamdin/views.py中打印看看

from kingadmin import app_setup#程序已启动就自动执行app_setup.kingadmin_auto_discover()from kingadmin.sites import siteprint('site',site.enable_admins)

运行程序

 

 (6)前端页面显示

 kingamdin/views.py

def app_index(request):    return render(request,'kingadmin/app_index.html',{
'site':site})

kingadmin/templates/app_index.html

{#templates/kingadmin/app_index.html#}{% extends 'kingadmin/index.html' %}{% block right-content-container %}
{% for app_name,app_tables in site.enable_admins.items %} {
{ app_name }}{
{ app_tables }} {% endfor %}
{% endblock %}

 

 

4.3.kingadmin model obj list页面开发

把前端页面做成表格的格式,跟admin后台显示一样

 

bootstrap table:  https://v3.bootcss.com/css/#tables

 

(1)kingadmin/app_index.html

{#templates/kingadmin/app_index.html#}{% extends 'kingadmin/index.html' %}{% block right-content-container %}
{% for app_name,app_tables in site.enable_admins.items %}
{% for model_name in app_tables %}
{% endfor %}
{
{ app_name }}
{ { model_name }} ADD Change
{% endfor %}
{% endblock %}

 

(2)crm/kingadmin.py注册三个model

#注册modelclass CustomerAdmin(object):    list_display = ['name','source','contact_type','contact','consultant','consult_content','status','date']    list_filter = ['source','consultant','status','date']    search_fields = ['contact','consultant__name']site.register(models.CustomerInfo,CustomerAdmin)site.register(models.Role)site.register(models.Menus)site.register(models.UserProfile)

 

(3)kingadmin/url.py

urlpatterns = [        url(r'^(\w+)/(\w+)/$', views.table_obj_list,name='table_obj_list'),]

 

(4)kingadmin/sites.py

class AdminSite(object):    .    .    .    def register(self,model_class,admin_class=None):        .        .        .         #获取app名字        app_name = model_class._meta.app_label        #获取表名        model_name = model_class._meta.model_name        #把model_class赋值给了admin_class,然后在视图中可以通过admin_class找到对应的model类(表名字)        admin_class.model = model_class        .        .        .

此时运行发现会报错

 

是因为我们在注册model的时候,有的写了自定义的model类,有的没写,而我们都统一的赋值,导致那些没写自定义model类(空的)赋值的时候就会报NoneType错误

 

django自带的自定义admin类的写法继承了ModelAdmin,那注册的时候为什么有的没写自定义admin类没有报错呢?

是因为继承的ModelAdmin帮我们写了(里面其实都定义为空了),我们模仿django admin的写法,也写个父类。

 

 

(5)kingadmin/admin_base.py

新建个admin_base.py,写个父类

# kingadmin/admin_base.pyclass BaseKingAdmin(object):    pass

 

(6)crm/kingadmin.py

# crm/kingadmin.pyfrom kingadmin.sites import sitefrom crm import modelsfrom kingadmin.admin_base import BaseKingAdmin# print('crm kingadmin....')#注册modelclass CustomerAdmin(BaseKingAdmin):    list_display = ['name','source','contact_type','contact','consultant','consult_content','status','date']    list_filter = ['source','consultant','status','date']    search_fields = ['contact','consultant__name']site.register(models.CustomerInfo,CustomerAdmin)site.register(models.Role)site.register(models.Menus)site.register(models.UserProfile)
crm/kingadmin.py

继承BaseKingAdmin

 

 (7)kingadmin/sites.py

# kingadmin/sites.pyfrom kingadmin.admin_base import BaseKingAdminclass AdminSite(object):    def __init__(self):        self.enable_admins = {}    #两个参数,一个表名,一个自定义的admin类    def register(self,model_class,admin_class=BaseKingAdmin):        '''注册admin表'''        # print('register',model_class,admin_class)        #获取app名字        app_name = model_class._meta.app_label        #获取表名        model_name = model_class._meta.model_name        #把model_class赋值给了admin_class,然后在视图中可以通过admin_class找到对应的model类(表名字)        admin_class.model = model_class        if app_name not in self.enable_admins:            self.enable_admins[app_name] = {}        self.enable_admins[app_name][model_name] = admin_class#实例化,就可以调用register方法site = AdminSite()
kingadmin/sites.py

 

现在运行程序,就正常了,访问:http://127.0.0.1:8000/kingadmin/

 

(8)取出model里面的值

kingadmin/views.py

@login_requireddef table_obj_list(request, app_name, model_name):    '''取出指定model里的数据返回给前端'''    #拿到admin_class后,通过它找到拿到model    admin_class = site.enable_admins[app_name][model_name]    querysets = admin_class.model.objects.all()    return render(request, 'kingadmin/table_obj_list.html',{
'querysets':querysets})

 

(9)templates/kingadmin/table_obj_list.html

{#kingadmin/templates/kingadmin/table_obj_list.html#}{% extends 'kingadmin/index.html' %}{% block right-content-container %}
{
{ querysets }}
{% endblock %}

现在拿到的是一个对象,但是有个问题就是:没注册三个model里面得到值是一样

 

 

 

因为没注册的三个mdoel都共享同一个BaseKingAdmin内存对象(三个model内存地址一样),我们只需要实例化就可以了(实例化后就都有单独的内存空间了)

修改kingadmin/sites.py

 

# kingadmin/sites.pyfrom kingadmin.admin_base import BaseKingAdminclass AdminSite(object):    def __init__(self):        self.enable_admins = {}    #两个参数,一个表名,一个自定义的admin类    def register(self,model_class,admin_class=None):        '''注册admin表'''        # print('register',model_class,admin_class)        #获取app名字        app_name = model_class._meta.app_label        #获取表名        model_name = model_class._meta.model_name        #把model_class赋值给了admin_class,然后在视图中可以通过admin_class找到对应的model类(表名字)        if not admin_class:            # 实例化,如果没写注册的类,就用BaseKingAdmin            admin_class = BaseKingAdmin()        else:            #如果写了注册的类,就实例化自己            admin_class = admin_class()        admin_class.model = model_class        if app_name not in self.enable_admins:            self.enable_admins[app_name] = {}        self.enable_admins[app_name][model_name] = admin_class#实例化,就可以调用register方法site = AdminSite()

 现在就可以取出对应model的数据了

 

转载地址:http://fiwfa.baihongyu.com/

你可能感兴趣的文章
showdialog弹出窗口刷新问题
查看>>
java
查看>>
Vue.js连接后台数据jsp页面  ̄▽ ̄
查看>>
关于程序的单元测试
查看>>
mysql内存优化
查看>>
都市求生日记第一篇
查看>>
Java集合---HashMap源码剖析
查看>>
SQL优化技巧
查看>>
thead 固定,tbody 超出滚动(附带改变滚动条样式)
查看>>
Dijkstra算法
查看>>
css 动画 和 响应式布局和兼容性
查看>>
csrf 跨站请求伪造相关以及django的中间件
查看>>
MySQL数据类型--与MySQL零距离接触2-11MySQL自动编号
查看>>
生日小助手源码运行的步骤
查看>>
Configuration python CGI in XAMPP in win-7
查看>>
bzoj 5006(洛谷 4547) [THUWC2017]Bipartite 随机二分图——期望DP
查看>>
CF 888E Maximum Subsequence——折半搜索
查看>>
欧几里德算法(辗转相除法)
查看>>
面试题1-----SVM和LR的异同
查看>>
MFC控件的SubclassDlgItem
查看>>