CRM手记-2 | Django

Posted 胡说八道

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CRM手记-2 | Django相关的知识,希望对你有一定的参考价值。

#################################### 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的功能

 

以上是关于CRM手记-2 | Django的主要内容,如果未能解决你的问题,请参考以下文章

CRM手记-4 | Django

CRM手记-1 | Django

CRM手记-5 | Django

CRM手记- 11 | Django

CRM手记-8 | Django

CRM手记-7 | Django