• 08/27 Django admin相关


    一、django-admin的简单回顾:

    admin: Django的后台数据管理的web版本

    1、admin

      a:models.py

         - 创建表

      b:admin.py

        - 注册表    admin.site.register(models.UserInfo)

      c:urls.py

       - url(r'^admin/', admin.site.urls),

      PS:

        1、动态生成url

        2、注册和生成url使用的都是admin.site

    二、django-admin的用法

    当我们创建登录admin的时候,里面会有增删改查,不仅仅是这些功能,我们可以通过以下的方式设置一些样式

    1、admin路由规则:

    /admin/app01/role/           查看角色列表
    /admin/app01/role/add/       添加角色
    /admin/app01/role/2/change/  编辑
    /admin/app01/role/2/delete/  删除
                
                
    /admin/app01/userinfo/           /admin/应用名/表名
    /admin/app01/userinfo/add/       /admin/应用名/表名/功能名
    
    /admin/app01/userinfo/1/change/ /admin/app01/userinfo/1/delete/

    2.自定义admin

    创建models

    from django.db import models
    
    # Create your models here.
    
    
    from django.db import models
    
    
    # Create your models here.
    
    
    class Author(models.Model):
        nid = models.AutoField(primary_key=True)
        name = models.CharField(max_length=32)
        age = models.IntegerField()
    
        # 与AuthorDetail建立一对一的关系
        authorDetail = models.OneToOneField(to="AuthorDetail", on_delete=models.CASCADE)
    
        def __str__(self):
            return self.name
    
    
    class AuthorDetail(models.Model):
        nid = models.AutoField(primary_key=True)
        birthday = models.DateField()
        telephone = models.BigIntegerField()
        addr = models.CharField(max_length=64)
    
    
    class Publish(models.Model):
        nid = models.AutoField(primary_key=True)
        name = models.CharField(max_length=32)
        city = models.CharField(max_length=32)
        email = models.EmailField()
    
        def __str__(self):
            return self.name
    
    
    class Book(models.Model):
        nid = models.AutoField(primary_key=True)
        title = models.CharField(max_length=32)
        publishDate = models.DateField()
        price = models.DecimalField(max_digits=5, decimal_places=2)
    
        # 与Publish建立一对多的关系,外键字段建立在多的一方
        publish = models.ForeignKey(to="Publish", to_field="nid", on_delete=models.CASCADE)
        # 与Author表建立多对多的关系,ManyToManyField可以建在两个模型中的任意一个,自动创建第三张表
        authors = models.ManyToManyField(to='Author', )
    
        def __str__(self):
            return self.title
    models.py

    在admin.py中只需要讲Mode中的某个类注册,即可在Admin中实现增删改查的功能,如:

    admin.site.register(models.Book)
    admin.site.register(models.Author)
    admin.site.register(models.Publish)

    自定义更多操作:利用ModelAdmin

    class Bookconfig(admin.ModelAdmin):       #自定义一个配置类,名字可以随意起,继承admin.ModelAdmin
        list_display = ['nid', 'title', 'publishDate', 'price']  #list_display,列表时,定制显示的列。
        list_filter = ['title', 'publish', 'authors']    #list_filter,列表时,定制右侧快速筛选。一对多或多对多更好用
        list_display_links = ['nid', 'title', 'publishDate', 'price']  #list_display_links,列表时,定制列可以点击跳转到编辑。
        search_fields = ['title', 'price']  #search_fields,列表时,模糊搜索的功能,
    
        def price_init(self, request, queryset):  #自定义actions 定义一个类,名字随意,需要三个参数
            queryset.update(price=0)  #函数内容,这个函数需要做什么,定制Action行为具体方法
    
        price_init.short_description = '价格归零'  #中文显示自定义Actions
        actions = [price_init]    #把写好的函数放入列表,可以多放几个
    
    
    admin.site.register(Book, Bookconfig)  #把类名写入注册的字段

    更多方法:https://www.cnblogs.com/yuanchenqi/articles/8323452.html#_label1

    二、admin源码

    单例模式

    单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在。当你希望在整个系统中,某个类只能出现一个实例时,单例对象就能派上用场。

    比如,某个服务器程序的配置信息存放在一个文件中,客户端通过一个 AppConfig 的类来读取配置文件的信息。如果在程序运行期间,有很多地方都需要使用配置文件的内容,也就是说,很多地方都需要创建 AppConfig 对象的实例,这就导致系统中存在多个 AppConfig 的实例对象,而这样会严重浪费内存资源,尤其是在配置文件内容很多的情况下。事实上,类似 AppConfig 这样的类,我们希望在程序运行期间只存在一个实例对象。

    class Settings():
        def __init__():
             self.app_namse=["app01","app02"]

    s=Settings()

    s.app_namse.append("app03")

    实现单例模式:

    (1)使用 __new__

    为了使类只能出现一个实例,我们可以使用 __new__ 来控制实例的创建过程,代码如下:
    
    class Settings(object):
        _instance = None
        def __new__(cls, *args, **kw):
            if not cls._instance:
                cls._instance = super(Settings, cls).__new__(cls, *args, **kw)
            return cls._instance
    s1=Settings()
    s2=Settings()

    print(s1==s2)#True
    print(id(s1))#32031408
    print(id(s2))#32031408
    结论:两个实例的id相同
    我们将类的实例和一个类变量 _instance 关联起来,如果 cls._instance 为 None 则创建实例,否则直接返回 cls._instance。

    (2)使用模块

    其实,Python 的模块就是天然的单例模式,因为模块在第一次导入时,会生成 .pyc 文件,当第二次导入时,就会直接加载 .pyc 文件,
    而不会再次执行模块代码。因此,我们只需把相关的函数和数据定义在一个模块中,就可以获得一个单例对象了。

     admin执行流程

    1.启动:

    django启动后,会加载settings中的install_app
               admin.py:
                    from django.contrib.admin.sites import AdminSite, site
                    autodiscover_modules('admin', register_to=site):加载每一个app下的admin.py文件

    2 注册
            源码:django.contrib.admin.sites模块
            class AdminSite(object):
                  
                      def __init__(self):
                            self._registry = {}
                  
                      def register(self,model,admin_class=None):
                           # 设置配置类
                           if not admin_class:
                                admin_class = ModelAdmin
                                
                           self._registry[model] = admin_class(model, self)        
                 
            site = AdminSite()
            这里应用的是一个单例模式,对于AdminSite类的一个单例模式,执行的每一个app中的每一个admin.site都是一个对象
          

           每一个app下的admin.py文件:
                from django.contrib import admin
                admin.site.register(Book,BookConfig)
                admin.site.register(Publish)

    3 设计url

  • 相关阅读:
    Building workspace has encountered a proble
    Eclipse异常关闭,IDE Exception Handler has encountered a problem An internal error has occurred
    jsp中写java代码的方法
    如何在jsp里面写java代码
    jsp中在java里面怎么调文本框里面的值?
    Typescript基本认识
    运行flutter run 报错Could not determine the dependencies of task ':app:compileDebugJavaWithJavac'.
    H5+原生webview实现APP的JavascriptBridge的使用
    vue mounted里使用window.onresize报错问题
    关于elmentui 抽屉 el-drawer 的slot插入的内容无法通过ref访问的问题
  • 原文地址:https://www.cnblogs.com/Mr-Murray/p/9544479.html
Copyright © 2020-2023  润新知