Django-admin組件

来源:https://www.cnblogs.com/yangqian007/archive/2018/08/28/9551710.html
-Advertisement-
Play Games

<!--done--> 知識預覽 Django 如何使用admin組件來對後臺數據進行管理的? Django admin如何實現後臺數據管理的?(admin源碼解析) 如何仿照admin實現一個自定義的增刪改查的組件? 回到頂部 Django 如何使用admin組件來對後臺數據進行管理的? 在每個a ...


知識預覽

回到頂部

Django 如何使用admin組件來對後臺數據進行管理的?

在每個app下的admin.py文件中進行註冊:
    from app名.models import 模型類名
    from django.contrib import admin
    
    admin.site.register(模型類名)
    
    class 自定義配置類名(admin.ModelAdmin):
        list_display = ["欄位名1","欄位名1"]
        
    admin.site.register(模型類名,自定義配置類名)

 

回到頂部

Django admin如何實現後臺數據管理的?(admin源碼解析)

一、啟動
    django啟動後,會載入settings中的INSTALLED_APPS
        from django.contrib import admin
    在__init.py中:
        from django.contrib.admin.sites import AdminSite, site    // 導入模塊的實例化對象,此為單例模式

        from django.utils.module_loading import autodiscover_modules
        def autodiscover():
            autodiscover_modules('admin', register_to=site)    //載入每一個app下的admin.py文件
    # 優先執行哪個app下的admin.py 是由settings中的INSTALLED_APPS的載入順序決定的
二、註冊
    admin.site.register(Author)
    
    class BookConfig(admin.ModelAdmin):
       pass
    admin.site.register(Book,BookConfig)
    
    admin.py---sites.py中:
        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()
        
        admin.site._registry --> {
            <class 'django.contrib.auth.models.Group'>:<django.contrib.auth.admin.GroupAdmin object at 0x0000000003E70DD8>,
            <class 'django.contrib.auth.models.User'>:<django.contrib.auth.admin.UserAdmin object at 0x0000000003E9DCC0>,
            <class 'app01.models.Author'>:ModelAdmin(Author),
            <class 'app01.models.AuthorDetail'>:ModelAdmin(AuthorDetail),
            <class 'app01.models.Book'>: BookConfig(Book),
            <class 'app01.models.Publish'>:PublishConfig(Publish),
        }
        在app下admin.py文件中註冊,admin.site._registry中才會有此鍵值對。
三、設計url
##### 一級url分發 #####
urlpatterns = [
    
    url(r"^my_admin/",([
                        url(r"^book/",app01_views.list_book),
                        url(r"^publish/",app01_views.list_publish),
                        url(r"^food/",app02_views.list_food),
                       ],None,None))
]


##### 二級url分發 #####
urlpatterns = [
    
    url(r"^my_admin/",([
                        url(r"^book/",([
                                        url(r"^$",app01_views.list_book),
                                        url(r"^add/$",app01_views.add_book),
                                        url(r"^(\d+)/change/$",app01_views.edit_book),
                                        url(r"^(\d+)/delete/$",app01_views.del_book),
                                       ],None,None)),
                        url(r"^publish/",app01_views.list_publish),
                        url(r"^food/",app02_views.list_food),
                       ],None,None))
]

在urls.py中:
    from django.conf.urls import url
    from django.contrib import admin
    from django.shortcuts import HttpResponse
    def listview(request):
    return HttpResponse("listview")


    def addview(request):
        return HttpResponse("addview")


    def changeview(request,id):
        return HttpResponse("changeview")


    def deleteview(request,id):
        return HttpResponse("deleteview")


    def get_urls_02():
        res = [
            url(r"^$",listview),
            url(r"^add/$",addview),
            url(r"^(\d+)/change/$",changeview),
            url(r"^(\d+)/delete/$",deleteview),
        ]
        return res


    def get_urls_01():
        res = []
        print("urls.py文件中admin.site._registry -->",admin.site._registry)
        """
        urls.py文件中admin.site._registry --> {
        <class 'django.contrib.auth.models.Group'>: <django.contrib.auth.admin.GroupAdmin object at 0x0000000003E70E10>, 
        <class 'django.contrib.auth.models.User'>: <django.contrib.auth.admin.UserAdmin object at 0x0000000003E9DCF8>, 
        <class 'app01.models.Author'>: <django.contrib.admin.options.ModelAdmin object at 0x0000000003EB0940>, 
        <class 'app01.models.AuthorDetail'>: <django.contrib.admin.options.ModelAdmin object at 0x0000000003EB0978>, 
        <class 'app01.models.Book'>: <app01.admin.BookConfig object at 0x0000000003EB09B0>, 
        <class 'app01.models.Publish'>: <app01.admin.PublishConfig object at 0x0000000003EB09E8>, 
        <class 'app02.models.Food'>: <django.contrib.admin.options.ModelAdmin object at 0x0000000003EB07F0>
        }
        """
        for model,config_obj in admin.site._registry.items():
            print("模型類變數model-->",model)
            print("配置類對象config_obj-->",config_obj)

            model_name = model._meta.model_name # 獲取字元串形式的模型類名
            app_label = model._meta.app_label # 獲取字元串形式的app名
            print("model_name-->{},type(model_name)-->{}".format(model_name,type(model_name)))
            print("app_label-->{},type(model_name)-->{}".format(app_label,type(app_label)))
            """
            模型類變數model--> <class 'django.contrib.auth.models.Group'>
            配置類對象config_obj--> auth.GroupAdmin
            model_name-->group,type(model_name)--><class 'str'>
            app_label-->auth,type(model_name)--><class 'str'>
            模型類變數model--> <class 'django.contrib.auth.models.User'>
            配置類對象config_obj--> auth.UserAdmin
            model_name-->user,type(model_name)--><class 'str'>
            app_label-->auth,type(model_name)--><class 'str'>
            模型類變數model--> <class 'app01.models.Author'>
            配置類對象config_obj--> app01.ModelAdmin
            model_name-->author,type(model_name)--><class 'str'>
            app_label-->app01,type(model_name)--><class 'str'>
            模型類變數model--> <class 'app01.models.AuthorDetail'>
            配置類對象config_obj--> app01.ModelAdmin
            model_name-->authordetail,type(model_name)--><class 'str'>
            app_label-->app01,type(model_name)--><class 'str'>
            模型類變數model--> <class 'app01.models.Book'>
            配置類對象config_obj--> app01.BookConfig
            model_name-->book,type(model_name)--><class 'str'>
            app_label-->app01,type(model_name)--><class 'str'>
            模型類變數model--> <class 'app01.models.Publish'>
            配置類對象config_obj--> app01.PublishConfig
            model_name-->publish,type(model_name)--><class 'str'>
            app_label-->app01,type(model_name)--><class 'str'>
            模型類變數model--> <class 'app02.models.Food'>
            配置類對象config_obj--> app02.ModelAdmin
            model_name-->food,type(model_name)--><class 'str'>
            app_label-->app02,type(model_name)--><class 'str'>
            """
            add_url = url(r"^{}/{}/".format(app_label,model_name),(get_urls_02(),None,None))
            res.append(add_url)
        return res


    urlpatterns = [
        url(r"^my_admin/",(get_urls_01(),None,None)),
    ]

 

回到頂部

如何仿照admin實現一個自定義的增刪改查的組件?

一、啟動
    1、創建一個與Django項目無關的,可以單獨分離出來用在多個項目上的名稱為my_admin的app:
        python manage.py startapp my_admin    
    2、創建兩個與Django項目有關的兩個app:
        python manage.py startapp app01
        python manage.py startapp app02
    3、在settings.py中的INSTALLED_APPS變數中添加:
        'app01.apps.App01Config',
        'app02.apps.App02Config',
        'my_admin.apps.MyAdminConfig',
    4、將my_admin、app01和app02中的admin.py文件全部刪除,重新分別在app01和app02中添加myAdmin.py
    5、app01下models.py中添加Book,Publish,AuthorDetail,Author類
    6、app02下models.py中添加Food類
    7、遷移資料庫:
        python manage.py makemigrations
        python manage.py migrate
    8、my_admin的app下有一個apps.py文件,在此文件中添加:
        from django.utils.module_loading import autodiscover_modules
        class MyAdminConfig(AppConfig):
            name = 'my_admin'

            def ready(self):
                autodiscover_modules("myAdmin")
二、註冊
    1、my_admin的app下創建一個python package的包,名稱為service
    2、在service文件夾下新建一個sites.py文件
    3、sites.py中添加以下代碼:
        class ModelMyAdmin():
            list_display = []
            
            def __init__(self,model):
                self.model = model
            
        
        class MyAdminSite():
            def __init__(self):
                self._registry = {}
                
            def register(self,model,my_admin_class = None):
                if not my_admin_class:
                    my_admin_class = ModelMyAdmin
                self._registry[model] = my_admin_class(model)
        
        
        site = MyAdminSite()
    4、在app01下的myAdmin.py中註冊模型類:
        from my_admin.service.sites import ModelMyAdmin,site
        from app01.models import Book,Publish,Author,AuthorDetail
        
        class BookConfig(ModelMyAdmin):
            list_display = ["title","publish_date","price"]
            
            
        site.register(Book,BookConfig)
        site.register(Publish)
        site.register(Author)
        site.register(AuthorDetail)
        
        print("app01下的site._registry-->",site._registry)
        啟動項目後,列印出此字典證明已經註冊成功
        {
            <class 'app01.models.Author'>: <my_admin.service.sites.ModelMyAdmin object at 0x0000000003EA70B8>, 
            <class 'app01.models.AuthorDetail'>: <my_admin.service.sites.ModelMyAdmin object at 0x0000000003EB1B00>, 
            <class 'app01.models.Book'>: <app01.myAdmin.BookConfig object at 0x0000000003EB1EB8>, 
            <class 'app01.models.Publish'>: <my_admin.service.sites.ModelMyAdmin object at 0x0000000003EB1EF0>
        }
三、設計url
    1、在urls.py文件中:
        from django.conf.urls import url
        from my_admin.service.sites import site
        
        urlpatterns = [
            url(r'^my_admin/',site.urls),
        ]
        
    2、在sites.py文件中的MyAdminSite類中繼續添加一個urls方法:
        from django.conf.urls import url
        def get_urls_01(self):
            res = []
            for model,config_obj in self._registry.items():
                model_name = model._meta.model_name
                app_label = model._meta.app_label
                add_url = url(r'{}/{}/'.format(app_label,model_name),config_obj.urls)    #config_obj:某個model的配置類(自定義配置類或者預設配置類)對象     
                res.append(add_url)
            return res
        
        @property
        def urls(self):
            return self.get_urls_01(),None,None
            
    3、在sites.py文件中的ModelMyAdmin類中繼續添加一個urls方法:
        from django.shortcuts import render
        def listview(self,request):
            print("self-->",self) # 當前訪問模型類的配置類對象
            print("self.model-->",self.model) # 當前訪問模型類
            
            data = self.model.objects.all()
            return render(request,"listview.html",{"data_list":data})    
            
        def addview(self,request):
            return HttpResponse("addview")

        def changeview(self,request, id):
            return HttpResponse("changeview")

        def deleteview(self,request, id):
            return HttpResponse("deleteview")    
            
        def get_urls_02(self):
            res = [
                url(r'^$',self.listview)
                url(r'^add/$',self.addview)
                url(r'^(\d+)/change/$',self.changeview)
                url(r'^(\d+)/delete/$',self.deleteview
            ]
            return res
        
        @property        
        def urls(self):
            return self.get_urls_02(),None,None
為什麼要將get_urls_02的方法寫入到ModelMyAdmin類中,而不寫在MyAdminSite類中?
    將get_urls_02寫入到MyAdminSite類中,由於單例模式造成返回的是同一個頁面,如果是簡單的返回一個HttpResponse對象,是可以的;
    但是現實需求是不同的表要展示不同的視圖數據而且不同的表要有不同的配置信息,故需要寫入在ModelMyAdmin類中。



您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 在看這篇文章之前,本人建議你先看看其他的關於這個問題的本質以及解決的方案。 我們做開發,通過SVN同步項目,連接的是遠程資料庫,同學在SVN導出的項目在Windows上可以運行,我在Windows上也可以運行,但是在Linux上就是不能運行--意思就是說什麼賬號,密碼,埠,許可權問題全都沒有。 但是 ...
  • OutOfMemoryError 問題相信很多朋友都遇到過,相對於常見的業務異常(數組越界、空指針等)來說這類問題是很難定位和解決的。 本文以最近碰到的一次線上記憶體溢出的定位、解決問題的方式展開;希望能對碰到類似問題的同學帶來思路和幫助。 ...
  • 1、基本類型包裝類 2、System類 3、Math類 4、Arrays類 5、大數據運算 ...
  • 有人讓我寫一下關於數據挖掘在金融方面的應用,再加上現在金融對數據方面的要求不斷提高,準備用兩篇隨筆來做個入門總結。 首先,在看這篇隨筆以前稍微補充一點金融方面的知識,因為我不是金融專業的,以下補充知識來自互聯網與個人整理,歡迎批評指正並補充說明。 1 先來瞭解一下什麼是金融市場呢? 通常狹義的金融市 ...
  • 變數定義 1.基礎定義 變數類型在變數名後 2.定義並賦值 3.類型推導 不用定義變數類型 4.簡寫(只能在函數內) 用":="代替"var" 5.定義多個變數並賦值 測試代碼 ...
  • 詳細教程 參考struts教程https://www.w3cschool.cn/struts_2/struts_configuration.html Struts2 基於MVC設計模式的web應用程式框架,它不僅僅是Struts1 的升級版本,更是一個全新的Struts架構。最初,是以WebWork ...
  • 一.文件的打開,open函數 打開模式有很多種 1. 'r': 以只讀方式打開文件。文件的指針將會放在文件的開頭。這是預設模式。 2. 'r+': 打開一個文件用於讀寫。文件指針將會放在文件的開頭,但寫入內容會寫到文件內容末尾。 3. 'w': 打開一個文件只用於寫入。如果該文件已存在則打開文件,並 ...
  • 1.什麼是servlet? Servlet(Servlet Applet),全稱Java Servlet,是用Java編寫的伺服器端程式。而這些Servlet都要實現Servlet這個介面。其主要功能在於互動式的瀏覽和修改數據,生成動態Web內容。Servlet運行於支持Java的應用伺服器中。 2 ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...