1. 程式人生 > 實用技巧 >仿製Django的admin元件完成的Xadmin元件設計——新的Xadmin元件的配置

仿製Django的admin元件完成的Xadmin元件設計——新的Xadmin元件的配置

既然我們要做一個Xadmin元件,那麼這個元件要有一定的複用的功能,所以要進行一系列的配置,當我們把這個元件複製到別的專案中,要知道如何使用

還是看一看整個專案的組織結構

app01和02是兩個我們一般的app,還有Xadmin也是一個建立的app,但是是Xadmin元件,所以在setting.py裡要把這三個app新增進去,這個沒什麼好說的

下面我們需要的就是仿照admin裡的原始碼寫一個方法

 1 from .decorators import register as register
 2 from .filters import (
 3     AllValuesFieldListFilter as AllValuesFieldListFilter,
4 BooleanFieldListFilter as BooleanFieldListFilter, 5 ChoicesFieldListFilter as ChoicesFieldListFilter, 6 DateFieldListFilter as DateFieldListFilter, 7 FieldListFilter as FieldListFilter, 8 ListFilter as ListFilter, 9 RelatedFieldListFilter as RelatedFieldListFilter, 10 RelatedOnlyFieldListFilter as RelatedOnlyFieldListFilter,
11 SimpleListFilter as SimpleListFilter, 12 ) 13 from .helpers import ACTION_CHECKBOX_NAME as ACTION_CHECKBOX_NAME 14 from .options import ( 15 HORIZONTAL as HORIZONTAL, 16 VERTICAL as VERTICAL, 17 ModelAdmin as ModelAdmin, 18 StackedInline as StackedInline, 19 TabularInline as TabularInline,
20 ) 21 from .sites import AdminSite as AdminSite, site as site 22 from . import checks as checks 23 24 def autodiscover() -> None: ...
admin的原始碼

admin裡的程式碼有個功能就是保證了django專案在啟動的時候直接執行所有admin.py這個檔案。那麼我們要讓Django啟動的時候執行所有的Xadmin檔案(這裡省略了一個操作:把各個app裡的admin檔案改名為Xadmin)。

現在主要看一下Xadmin裡面的幾個py檔案,要改的就是app.py

"""
Xadmin/app.py
"""

from django.apps import AppConfig
from django.utils.module_loading import autodiscover_modules

class XadminConfig(AppConfig):
    name = 'Xadmin'

    def ready(self):
        autodiscover_modules('Xadmin')

上面的這段程式碼就保證了Django專案執行 到時候執行每個app下名字為Xadmin這個檔案。

大概整個流程是這樣的:

settings.py裡制定了這個app裡的類(倒數第三行)

 1 INSTALLED_APPS = [
 2     'django.contrib.admin',
 3     'django.contrib.auth',
 4     'django.contrib.contenttypes',
 5     'django.contrib.sessions',
 6     'django.contrib.messages',
 7     'django.contrib.staticfiles',
 8     'Xadmin.apps.XadminConfig',
 9     'app01.apps.App01Config',
10     'app02.apps.App02Config'
11 ]
settings.py

這個類裡的ready方法是在這個類一旦被載入後直接執行的方法。

然後要按照admin的方式構造一個類似與admin.site的單例物件,因為我們要做的是一個元件,就把整個Xadmin做成一個元件

 1 """
 2 /Xadmin/service/Xadmin.py
 3 """
 4 class modelXadmin(object):
 5     def __init__(self,model,site):
 6         self.model = model
 7         self.site = site
 8 
 9 class XadminSite(object):
10     def __init__(self,name = 'admin'):
11         self._registry = {}
12 
13 
14     def register(self,model,admin_class=None,**options):
15         if not admin_class:
16             admin_class = modelXadmin
17 
18         self._registry[model] = admin_class(model,self)
19 
20 site = XadminSite() #基於模組的單例物件
Xadmin.py

然後就可以在各個app裡引入這個單例物件了,下面只列出了app01裡的註冊方法

 1 #下面這個admin的元件多久不用了
 2 #from django.contrib import admin
 3 
 4 # Register your models here.
 5 
 6 from Xadmin.service.Xadmin import site
 7 from . import models
 8 #table的註冊
 9 site.register(models.Books)
10 site.register(models.Publisher)
app01/Xadmin.py

這樣就回到我們前面講的admin的使用了。

url的封裝

前面一張我們瞭解了URL的設計思路,但是我們需要把這個URL封裝到Xadmin這個包中以備後期使用。這個URL的封裝還是有點意思的,先看看Django原始碼裡urls.py裡有下面的一行程式碼

path('admin/', admin.site.urls),

點進去看一看這個site裡的urls到底是個什麼

@property
def urls(self) -> Tuple[List[URLResolver], str, str]: ...

還是通過property裝飾器把類裡的方法變成了屬性,那麼在url裡直接通過呼叫直接就運行了(沒有裝飾器的話必須加括號才能執行)

內建了URL分發的XadminSite類

class XadminSite(object):
    def __init__(self,name = 'admin'):
        self._registry = {}


    def register(self,model,admin_class=None,**options):
        if not admin_class:
            admin_class = modelXadmin

        self._registry[model] = admin_class(model,self)

    @property
    def urls(self):
        return self.get_urls(),None,None

    def get_urls(self):
        temp = []
        for model,admin_class_obj in self._registry.items():
            model_name = model._meta.model_name
            app_name = model._meta.app_label
            temp.append(url(r"^{0}/{1}/".format(app_name,model_name),self.urls2),)
        return temp

    @property
    def urls2(self):

        return self.get_urls_2(),None,None


    def get_urls_2(self):
        temp = []
        temp.append(url(r'^$',self.list_view))
        temp.append(url(r'^add/$',self.add_view))
        temp.append(url(r'^(\d+)/change/$',self.change_view))
        temp.append(url(r'^(\d+)/delete/$',self.delete_view))
        return temp

    def list_view(self,request):
        return HttpResponse('list_view')

    def add_view(self,request):
        return HttpResponse('list_view')

    def change_view(self,request,id):
        return HttpResponse('list_view')

    def delete_view(self,request,id):
        return HttpResponse('list_view')
封裝了URL分發的XadminSite

在這裡的檢視我們只是通過程式碼實現了分發的效果。

後面就是要完成模板的設計了。