zoukankan      html  css  js  c++  java
  • Day 76 CRM业务——stark组件

    stark组件

    介绍

    stark 组件,是一个帮助开发者快速实现数据库表的增删改查+。

    目标

    10s 完成一张表的增删改查

    前戏

    1、django 项目启动时,自定义执行某个 py 文件

    django 启动时,且在读取项目中 路由加载 之前执行某个 py 文件

    在任意 app 的 apps.py 中的 Config 类中定义 ready 方法,并调用 autodiscover_modules 

    from django.apps import AppConfig
    from django.utils.module_loading import autodiscover_modules
    
    class App02Config(AppConfig):
        name = 'app02'
    
        def ready(self):
            autodiscover_modules('xxx')

    django 在启动时们就会去已注册的所有 app 的目录下找 xxx.py 并自动导入。

    如果发现执行了两次,是因为 django 内部的自动重启导致的:

      使用命令:python manage.py runserver 127.0.0.1:8000 --noreload

      pycharm:Edit Configurations ——> Additional options 输入: --noreload

    提示:

      如果 xxx.py 执行的代码向 "某个神奇的地方" 放入了一些值,之后的路由加载时,可以去"某个神奇的地方"读取到原来设置的值

    2、单例模式

    多例模式

    class Foo:
        pass
    
    obj01 = Foo()
    obj01.name = 'ysg'
    print(obj01)        # <__main__.Foo object at 0x000001D154C76128>
    
    obj02 = Foo()
    # print(obj02.name)   # AttributeError: 'Foo' object has no attribute 'name'
    
    print(obj02)        # <__main__.Foo object at 0x000001D154C76278>

    单例模式

    单:一个。

    例:实例,对象

    如果以后存在一个单例模式的对象,可以现在此对象中放入一个值,然后再在其他的文件中导入该对象,通过对象再次将值获取到。

    commons.py

    class Foo():
        pass
    
    site = Foo()

    app02.py

    import commons
    
    print('app02:', commons.site.name)

    app01.py

    import commons
    
    app01 = commons.site
    app01.name = 'ysg'      # <commons.Foo object at 0x0000021DF8C56208>
    print(app01)
    
    
    import commons
    
    app02 = commons.site
    print(app02.name)       # ysg
    print(app02)            # <commons.Foo object at 0x0000021DF8C56208>
    
    import app02            # <commons.Foo object at 0x0000029587E76198>
                            # app02: ysg

    通过 python 模块导入的特性,在 python 中,如果已经导入过的文件再次被重新的导入的时候,python不会在重新解释一遍,而是选择从内存中直接将原来的值拿来用,公用一块内存地址。

    3、django路由分发的本质:include

    方法一:

    from django.conf.urls import url, include
    from django.contrib import admin
    
    
    urlpatterns = [
        url(r'^rbac/', include(('rbac.urls', 'rbac'))),
    ]

    方法二:

    include 函数主要返回有是哪个元素的元组

    第一个参数是 urls 文件对象,通过此对象可以获取 urls.patterns 获取分发的路由

    from django.urls import path,re_path,include
    from django.conf.urls import url
    
    print('this is url')
    urlpatterns = [
        url(r'web01/', (urls,app_name,namespace))
    ]

    方法三:

    在源码内部,读取路由时:

      如果第一个参数有:urls.patterns 属性,那么子路由就从该属性中获取。

      如果第一个参数无:urls.patterns 属性,那么子路由就是第一个参数。

    from django.contrib import admin
    from django.urls import path,re_path,include
    from django.conf.urls import url
    from app02 import views
    
    print('this is url')
    urlpatterns = [
    
        path('admin/', admin.site.urls),
        path('index/', views.index),
        url(r'web01/', ([
                          url(r'^web/', views.index),
                          url(r'^home/', views.login)
                      ], 'appname', 'namespace'))
    ]

    stark组件的准备工作

    1、创建 django project

     并创建 app01、app02、stark 三个应用

    2、创建解除业务表

    app01

    部门表

    class Depart(models.Model):
        '''
        部门表
        '''
        title = models.CharField(verbose_name='部门名称',max_length=32)

    用户表

    class UserInfo(models.Model):
        '''
        用户表
        '''
        name = models.CharField(verbose_name='用户名称',max_length=32)
        age = models.CharField(verbose_name='年龄',max_length=32)
        email = models.CharField(verbose_name='Email',max_length=32)
        depart = models.ForeignKey(verbose_name='部门ID',to=Depart,on_delete=models.CASCADE)

    app02

    class Host(models.Model):
        '''
        主机表
        '''
        host = models.CharField(verbose_name='主机名称',max_length=32)
        ip = models.GenericIPAddressField(verbose_name='IP')

    数据库迁移

    __init__.py

    import pymysql
    pymysql.install_as_MySQLdb()

    Terminal 命令行

    python manage.py makemigrations
    python manage.py migrate

    stark组件实现

    为 app 中的每个 model 类自动创建 URL 以及相关视图函数

    url.py

    from django.contrib import admin
    from django.urls import path
    from django.conf.urls import url
    from stark.service.v1 import site
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        url(r'^stark/', site.urls),
    ]
    View Code

    app01/models.py

    from django.db import models
    
    # Create your models here.
    
    class Depart(models.Model):
        '''
        部门表
        '''
        title = models.CharField(verbose_name='部门名称',max_length=32)
    
    class UserInfo(models.Model):
        '''
        用户表
        '''
        name = models.CharField(verbose_name='用户名称',max_length=32)
        age = models.CharField(verbose_name='年龄',max_length=32)
        email = models.CharField(verbose_name='Email',max_length=32)
        depart = models.ForeignKey(verbose_name='部门ID',to=Depart,on_delete=models.CASCADE)
    View Code

    app02/models.py

    from django.db import models
    
    # Create your models here.
    
    class Host(models.Model):
        '''
        主机表
        '''
        host = models.CharField(verbose_name='主机名称',max_length=32)
        ip = models.GenericIPAddressField(verbose_name='IP')
    
    class Role(models.Model):
        '''
        角色表
        '''
        title = models.CharField(verbose_name='角色名称',max_length=32)
    View Code

    app01/stark.py

    from django.shortcuts import HttpResponse
    
    from stark.service.v1 import site
    from app01 import models
    
    
    
    class DepartHandler:
        def __init__(self, model_class):
            self.model_class = model_class
    
        def list_view(self, request):
            '''
            部门列表界面
            :param request:
            :return:
            '''
            return HttpResponse('部门列表界面')
    
        def add_view(self, request):
            '''
            部门列表界面
            :param request:
            :return:
            '''
            pass
    
        def edit_view(self, request, pk):
            '''
            部门列表界面
            :param request:
            :return:
            '''
            pass
    
        def del_view(self, request, pk):
            '''
            部门列表界面
            :param request:
            :return:
            '''
            pass
    
    
    class UserInfoHandler:
        def __init__(self, model_class):
            self.model_class = model_class
    
        def list_view(self, request):
            '''
            部门列表界面
            :param request:
            :return:
            '''
            return HttpResponse('用户列表界面')
    
        def add_view(self, request):
            '''
            部门列表界面
            :param request:
            :return:
            '''
            pass
    
        def edit_view(self, request, pk):
            '''
            部门列表界面
            :param request:
            :return:
            '''
            pass
    
        def del_view(self, request, pk):
            '''
            部门列表界面
            :param request:
            :return:
            '''
            pass
    
    
    site.register(models.Depart, DepartHandler)
    site.register(models.UserInfo, UserInfoHandler)
    View Code

    app02/stark.py

    from django.shortcuts import HttpResponse
    
    from stark.service.v1 import site
    from app02 import models
    
    
    class HostHandler:
        def __init__(self, model_class):
            self.model_class = model_class
    
        def list_view(self, request):
            '''
            部门列表界面
            :param request:
            :return:
            '''
            return HttpResponse('主机列表界面')
    
        def add_view(self, request):
            '''
            部门列表界面
            :param request:
            :return:
            '''
            pass
    
        def edit_view(self, request, pk):
            '''
            部门列表界面
            :param request:
            :return:
            '''
            pass
    
        def del_view(self, request, pk):
            '''
            部门列表界面
            :param request:
            :return:
            '''
            pass
    
    
    site.register(models.Host, HostHandler)
    
    
    class RoleHandler:
        def __init__(self, model_class):
            self.model_class = model_class
    
        def list_view(self, request):
            '''
            部门列表界面
            :param request:
            :return:
            '''
            return HttpResponse('角色列表界面')
    
        def add_view(self, request):
            '''
            部门列表界面
            :param request:
            :return:
            '''
            pass
    
        def edit_view(self, request, pk):
            '''
            部门列表界面
            :param request:
            :return:
            '''
            pass
    
        def del_view(self, request, pk):
            '''
            部门列表界面
            :param request:
            :return:
            '''
            pass
    
    
    site.register(models.Role, RoleHandler)
    View Code

    v1.py

    from django.conf.urls import url
    
    
    class StarkSite(object):
        def __init__(self):
            self._registry = []
            self.app_name = 'stark'
            self.namespace = 'stark'
    
        def register(self, model_class, handler_class):
            '''
    
            :param model_class: model 是数据库表对应的类
            :param handler_class: 处理请求的视图函数所在的类
            :return:
            '''
    
            self._registry.append({'model_class': model_class, 'handler': handler_class(model_class)})
    
        def get_urls(self):
            patterns = []
            for item in self._registry:
                model_class = item['model_class']
                handler = item['handler']
                # model_class._meta.app_label 获取数据库表所在的应用名
                # model_class._meta.model_name 获取数据库表的表名称
                # print(model_class._meta.app_label,model_class._meta.model_name)
                app_label, model_name = model_class._meta.app_label, model_class._meta.model_name
                patterns.append(url(r'%s/%s/list/$' % (app_label, model_name), handler.list_view))
                patterns.append(url(r'%s/%s/add/$' % (app_label, model_name), handler.add_view))
                patterns.append(url(r'%s/%s/edit/(?P<pk>d+)/$' % (app_label, model_name), handler.edit_view))
                patterns.append(url(r'%s/%s/del/(?P<pk>d+)/$' % (app_label, model_name), handler.del_view))
    
            return patterns
    
        @property
        def urls(self):
            return self.get_urls(), self.app_name, self.namespace
    
    
    site = StarkSite()
    View Code

    stark组件开发之提取公共视图函数

    # -*- coding: utf-8 -*-
    
    # @File    : v1.py
    # @Date    : 2020-06-16
    # @Author  : Administrator
    from django.conf.urls import url
    from django.shortcuts import render, HttpResponse
    
    # stark组件开发之提取公共视图函数
    class StarkHandler:
        def __init__(self, model_class):
            self.model_class = model_class
    
        def list_view(self, request):
            '''
            部门列表界面
            :param request:
            :return:
            '''
            data_list = self.model_class.objects.all()
            return render(request,'stark/changelist.html',locals())
    
        def add_view(self, request):
            '''
            部门列表界面
            :param request:
            :return:
            '''
            return HttpResponse('添加界面')
    
        def edit_view(self, request, pk):
            '''
            部门列表界面
            :param request:
            :return:
            '''
            return HttpResponse('编辑界面')
    
        def del_view(self, request, pk):
            '''
            部门列表界面
            :param request:
            :return:
            '''
            return HttpResponse('删除界面')
    
    
    # 为 app 中的每个 model 类自动创建 URL 以及相关视图函数
    class StarkSite(object):
        def __init__(self):
            self._registry = []
            self.app_name = 'stark'
            self.namespace = 'stark'
    
        def register(self, model_class, handler_class=None):
            '''
    
            :param model_class: model 是数据库表对应的类
            :param handler_class: 处理请求的视图函数所在的类
            :return:
            '''
            if not handler_class:
                handler_class = StarkHandler
            self._registry.append({'model_class': model_class, 'handler': handler_class(model_class)})
    
        def get_urls(self):
            patterns = []
            for item in self._registry:
                model_class = item['model_class']
                handler = item['handler']
                # model_class._meta.app_label 获取数据库表所在的应用名
                # model_class._meta.model_name 获取数据库表的表名称
                # print(model_class._meta.app_label,model_class._meta.model_name)
                app_label, model_name = model_class._meta.app_label, model_class._meta.model_name
                patterns.append(url(r'%s/%s/list/$' % (app_label, model_name), handler.list_view))
                patterns.append(url(r'%s/%s/add/$' % (app_label, model_name), handler.add_view))
                patterns.append(url(r'%s/%s/edit/(?P<pk>d+)/$' % (app_label, model_name), handler.edit_view))
                patterns.append(url(r'%s/%s/del/(?P<pk>d+)/$' % (app_label, model_name), handler.del_view))
    
            return patterns
    
        @property
        def urls(self):
            return self.get_urls(), self.app_name, self.namespace
    
    
    site = StarkSite()
    View Code

    stark组件开发之URL分发和默认Handler及别名

    app01/stark.py

    from django.shortcuts import HttpResponse
    from django.conf.urls import url
    from stark.service.v1 import site, StarkHandler
    from app01 import models
    
    
    class DepartHandler(StarkHandler):
        def extra_urls(self):
            return [url(r'^update/(?P<pk>d+)/$', self.update_view)]
    
        def update_view(self, request, pk):
            return HttpResponse('修改密码')
    
    
    class UserInfoHandler(StarkHandler):
        pass
    
    
    site.register(models.Depart, DepartHandler, prev='one')
    site.register(models.Depart, DepartHandler)
    site.register(models.UserInfo, UserInfoHandler)
    View Code

    v1.py

    class StarkHandler:
    
        # stark组件开发之提取公共视图函数
        def __init__(self, model_class, prev):
            self.model_class = model_class
            self.prev = prev
    
        def list_view(self, request):
            '''
            部门列表界面
            :param request:
            :return:
            '''
            data_list = self.model_class.objects.all()
            return render(request, 'stark/changelist.html', locals())
    
        def add_view(self, request):
            '''
            部门列表界面
            :param request:
            :return:
            '''
            return HttpResponse('添加界面')
    
        def edit_view(self, request, pk):
            '''
            部门列表界面
            :param request:
            :return:
            '''
            return HttpResponse('编辑界面')
    
        def del_view(self, request, pk):
            '''
            部门列表界面
            :param request:
            :return:
            '''
            return HttpResponse('删除界面')
    
        # stark组件开发之URL分发和默认Handler 及别名
        def get_url_name(self, param):
            app_label, model_name = self.model_class._meta.app_label, self.model_class._meta.model_name
            if self.prev:
                return '%s_%s_%s_%s' % (app_label, model_name, self.prev, param)
            return '%s_%s_%s' % (app_label, model_name, param)
    
        @property
        def get_list_url_name(self):
            '''
            获取列表界面的 url 的 name
            :return:
            '''
            return self.get_url_name('list')
    
        @property
        def get_add_url_name(self):
            '''
            获取添加界面的 url 的 name
            :return:
            '''
            return self.get_url_name('add')
    
        @property
        def get_edit_url_name(self):
            '''
            获取编辑界面的 url 的 name
            :return:
            '''
            return self.get_url_name('edit')
    
        @property
        def get_del_url_name(self):
            '''
            获取删除界面的 url 的 name
            :return:
            '''
            return self.get_url_name('del')
    
        def get_urls(self):
            '''
            重写 get_urls 可以修改所要生成的 url,和减少 url
            :return:
            '''
            patterns = [
                url(r'^list/$', self.list_view, name=self.get_list_url_name),
                url(r'^add/$', self.add_view, name=self.get_add_url_name),
                url(r'^edit/(?P<pk>d+)/$', self.edit_view, name=self.get_edit_url_name),
                url(r'^del/(?P<pk>d+)/$', self.del_view, name=self.get_del_url_name),
            ]
            patterns.extend(self.extra_urls())
            return patterns
    
        def extra_urls(self):
            '''
            重写 extra_urls 可以增加 url
            :return:
            '''
            return []
    View Code

    stark组件开发之列表页面自定义函数扩展

    app01/start.py

    from stark.service.v1 import site, StarkHandler
    from django.utils.safestring import mark_safe
    from app01 import models
    
    
    class DepartHandler(StarkHandler):
        # 自定义页面显示的列(表头和内容)
        def display_edit(self, obj=None, is_header=None):
            if is_header:
                return '编辑'
            return mark_safe('<a href="#">编辑</a>')
    
        def display_del(self, obj=None, is_header=None):
            if is_header:
                return '删除'
            return mark_safe('<a href="#">删除</a>')
    
        list_display = ['id', 'title', display_edit, display_del]
    View Code

    v1.py

    from django.conf.urls import url
    from django.shortcuts import render, HttpResponse
    from types import FunctionType
    
    
    # stark组件开发之提取公共视图函数
    class StarkHandler:
        # 定制页面显示的列
        list_display = []
    
        def __init__(self, model_class, prev):
            self.model_class = model_class
            self.prev = prev
    
        def get_list_display(self):
            '''
            获取页面上应该显示的列,预留的自定义扩展。如:以后可以根据用户权限的不同显示对应的列
            :return:
            '''
            value = []
            value.extend(self.list_display)
            return value
    
        def list_view(self, request):
            '''
            部门列表界面
            :param request:
            :return:
            '''
            # 1、处理表格的表头
            # ###### stark 组件开发之列表页面定制列 ######
            # 页面要显示的列
            # 用户访问的表 models.UserInfo  ['name','age','email','depart']
            header_list = []
            list_display = self.get_list_display()
            # 支持 StarkHandler 为空
            if list_display:
                for key_or_fun in list_display:
                    if isinstance(key_or_fun, FunctionType):
                        verbose_name = key_or_fun(self, obj=None, is_header=True)
                    else:
                        verbose_name = self.model_class._meta.get_field(key_or_fun).verbose_name
                    header_list.append(verbose_name)
            else:
                header_list.append(self.model_class._meta.model_name)
            # 处理表的内容
            data_list = self.model_class.objects.all()
            body_list = []
            for row in data_list:
                tr_list = []
                if list_display:
                    for key_or_fun in list_display:
                        if isinstance(key_or_fun, FunctionType):
                            tr_list.append(key_or_fun(self, row, is_header=False))
                        else:
                            tr_list.append(getattr(row, key_or_fun))
                else:
                    tr_list.append(row)
                body_list.append(tr_list)
            return render(request, 'stark/changelist.html', locals())
    View Code
  • 相关阅读:
    myaql常用函数
    mysql常用表/视图管理语句
    mysql中select五种子句和统计函数
    mysql里表以及列的增删改查
    mysql列类型
    如何删除openfire for苹果,彻底卸载!
    XMPP 服务器 Openfire 的 Emoji 支持问题(进行部分修改)
    iOS5.1下emoji表情显示方框的解决办法
    iOS 获取字符串中的单个字符
    iOS XMPP之常见错误一:(<failure xmlns="urn:ietf:params:xml:ns:xmpp-sasl"><not-authorized/></failure>)
  • 原文地址:https://www.cnblogs.com/ysging/p/13138926.html
Copyright © 2011-2022 走看看