zoukankan      html  css  js  c++  java
  • 模拟django 后台管理

    ---恢复内容开始---

    1 模拟admi启动自动执行admin相关应用,这里我们将自己的文件叫做myadmin,在我们的app01应用下创建myadmin.py文件

    在我们创建的myadmin应用中的app下写入固定方法,使用的是atuodiscover_moudels自动检索文件名并在启动第一时间执行该文件

    from django.apps import AppConfig
    from django.utils.module_loading import autodiscover_modules
    
    class MyadminConfig(AppConfig):
        name = 'myadmin'
        def ready(self):
            return autodiscover_modules('myadmin')

    2 模拟admin注册方法,写出模拟源码,在myadmin文件下创建service文件,名字我自己瞎起的一个,在该文件下创建myadmin

    写入模拟django的admin数据模型表的注册源码,注册类和模型表相对应的配置类

    配置类类名
    class ModelMyadmin(object):
    
    
    
    
    
    #注册模型表源码
    class MyadminSite(object):
        def __init__(self, name='admin'):
            self._registry = {}  # model_class class -> admin_class instance
    
        def register(self, model, admin_class=None, **options):
            if not admin_class:
                admin_class = ModelMyadmin
                # Instantiate the admin class to save in the registry
            self._registry[model] = admin_class(model)

    重点:在配置类中self就是我们操作的模型表,

    设置路由

     首先要搞清楚路由分组的本质,他是用url包裹的前面是路由的路由名称,逗号后边可以跟着的是视图函数的函数名,或者是二级的路由名称加上函数视图的函数名,在加上两个None,需要注意的是一级路由后面不管是什么内容必须用元组的形式给包裹起来。

    这里的路由生成模拟admin路由生成的方式在注册的源码和模型表的配置类中生成。

    在注册源码中生成模型表查看的一级路由:

       def get_urls(self):
    
            urls = []
            for model_class,config_obj in self._registry.items():       
           config_obj拿到的是模型表相对应的配置类
    #我们通过注册在源码的大字典中可以通过——meta.app_label取出模型表所在应用名,和 #_meta.model_name 取出模型表名 app_label= model_class._meta.app_label model_name = model_class._meta.model_name #通过拼接后生成urls形成一级路由, urls.append( url(r'^%s/%s/'%(app_label,model_name),config_obj.urls) ) return urls @property def urls(self): return self.get_urls(),None,None

     二级路由就涉及到模型表的数据操作了,这里不能在注册源码中生成了,因为模板导入使用源码后就形成了单例模式,如果在注册源码生成二级路由那么生成的所有表操作都是一样的了,

    但是表的具体操作又不可能是一样的所以要在模型表相对应的配置类中去生成二级路由:

     @property
        def urls(self):
            urls = [
                url(r'^$',self.list_view,name='%s_%s_%s'%(self.app_label,self.model_name,'list')),
                url(r'^add/',self.add_view,name='%s_%s_%s'%(self.app_label,self.model_name,'add')),
                url(r'^update/(d+)/',self.update_view,name='%s_%s_%s'%(self.app_label,self.model_name,'update')),
                url(r'^delete/(d+)/',self.delete_view,name='%s_%s_%s'%(self.app_label,self.model_name,'delete')),
            ]
            return urls,None,None

    路由生成以后就是对模型表操作设计到表的展示,和表数据的增删改查;

    其中在表的展示时我们不知道用户到底要展示什么数据,所以我们在配置类设置一个默认的展示,只展示模型表中的一个个对象通过__str__方法展示对象名。在暴露用户的注册表中提供给用户可以自己定制的方法,用户自己写了就用用户的用户如果不写就是使用我们自己默认的
    在配置类中默认list_play

    class ModelMyadmin(object):
        list_play = ['__str__',]

    在配置类中做判断如果用户没有对list_play设置,那么就使用默认的

     def get_new_list_play(self):
            tmp = []
            tmp.append(ModelMyadmin.check_col)
            tmp.extend(self.list_play)
            if not self.list_play_links:
                tmp.append(ModelMyadmin.edit_col)
            tmp.append(ModelMyadmin.delete_col)
            return tmp

    展示数据内容前台使用table标签进行渲染,在后台的数据处理上就要将表单的处理分为表头展示和表单内容展示,表头想要展示用中文的话,可以现在模型表设置 如:verbose_name='书籍名,

    在使用配置类._meta的方法去点出getfield()方法拿到verbose_name

    表头展示:

      def get_head(self):
            head_list = []
            for field_or_func in self.config_obj.get_new_list_play():
                if isinstance(field_or_func, str):
                    if field_or_func == '__str__':
                        head_list.append((self.config_obj.model._meta.model_name).upper())
                    else:
                        val = self.config_obj.model._meta.get_field(field_or_func).verbose_name
                        head_list.append(val)
                else:
                    val = field_or_func(self.config_obj, is_head=True)
                    head_list.append(val)
            return head_list

    表单内容展示:

        def get_body(self):
            # 表单展示
            body_list = []
            for obj in self.page_queryset:
                print(obj.pk)
                tmp = []
                for field_or_func in self.config_obj.get_new_list_play():
                    if isinstance(field_or_func, str):
                        val = getattr(obj, field_or_func)
                        if field_or_func in self.config_obj.list_play_links:
                            _url = self.config_obj.get_reverse('update', obj)
                            val = mark_safe('<a href="%s">%s</a>' % (_url, val))
                    else:
                        val = field_or_func(self.config_obj, obj=obj)
                    tmp.append(val)
                body_list.append(tmp)
            return body_list

    ---恢复内容结束---

  • 相关阅读:
    sqlserver用windows方式验证登录踩过的坑
    jdk8对象集合转map集合
    监听程序当前无法识别连接描述符中请求的服务解决方案
    Java上传文件至SFTP服务器
    记一次学习kibaba踩过的坑(Windows环境)
    CSRF跨站请求伪造与XSS跨域脚本攻击讨论
    LVS简单搭建(一)
    LVS+keepalived简单搭建(二)
    JZ2440开发板学习 1. 刚接触开发板, 安装驱动
    用STM32CubeMX创建FreeRTOS项目
  • 原文地址:https://www.cnblogs.com/1624413646hxy/p/11299109.html
Copyright © 2011-2022 走看看