仿製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,admin的原始碼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裡的程式碼有個功能就是保證了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
在這裡的檢視我們只是通過程式碼實現了分發的效果。
後面就是要完成模板的設計了。