最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Django中自定義admin Xadmin的實現(xiàn)代碼

 更新時間:2019年08月09日 14:48:23   作者:一抹淺笑  
這篇文章主要介紹了Django中自定義admin---Xadmin的實現(xiàn)代碼,本文通過實例代碼給大家介紹的非常詳細,具有一定的參考借鑒價值 ,需要的朋友可以參考下

在Django框架中,自帶一個后臺管理頁面admin,這個管理頁面很全,但是,有些并不是我們需要的,所以我們可以根據(jù)admin的實現(xiàn)流程來自定義自己的需求,即根據(jù)admin的實現(xiàn)方式來實現(xiàn)自定制--Xadmin

首先,我們先解析admin的流程,在Django中,我們在創(chuàng)建項目的時候,Django自帶一個admin的url,實現(xiàn)了不同模型表的增刪改查,那么admin是如何實現(xiàn)url的分發(fā)的?

我們可以從三部分來看admin的路由分發(fā)實現(xiàn)

1,啟動

我們可以通過from django.contrib import admin來看admin是如何啟動的

Django啟動后,會在manage.py文件中加載配置文件settings.py  ,在settings.py中有一個INSTALLED_APPS這個配置項,Django會按照配置項的內(nèi)容一次加載每一個app.

# Application definition

INSTALLED_APPS = [
 'django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'Xadmin.apps.XadminConfig',
 'blogs.apps.BlogsConfig',
 'bigs.apps.BigsConfig',
]

加載到django.contrib.admin時,會加載admin相關的,我們點擊admin,進入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)

執(zhí)行auto_discover這個接口,會自動的加載所有APP中的admin.py這個文件,這就是admin的啟動文件

2,注冊

自動加載所有APP下的admin.py文件時,會一次記錄所有執(zhí)行了admin.site.register(模型類)這個方法的模型類,從而完成模型類的注冊。

所有的模型類都執(zhí)行admin.site.register()這個方法后完成的注冊,那么這個方法內(nèi)部都做了些什么?

我們可以點擊site進入admin的源碼中,得到這個:site = AdminSite()  site是一個對象,是AdminSite這個類的一個對象,并且是一個單例對象,那么我們就可以肯定,register是這個單例對象的一個方法,那這個方法中到底做了什么?

class AdminSite(object):
 """
 An AdminSite object encapsulates an instance of the Django admin application, ready
 to be hooked in to your URLconf. Models are registered with the AdminSite using the
 register() method, and the get_urls() method can then be used to access Django view
 functions that present a full admin interface for the collection of registered
 models.
 """
 def __init__(self, name='admin'):
 self._registry = {} # model_class class -> admin_class instance
 self.name = name
 # 關于register的方法
 def register(self, model_or_iterable, admin_class=None, **options):
 if not admin_class:
  admin_class = ModelAdmin
 # Instantiate the admin class to save in the registry
 self._registry[model] = admin_class(model, self)
 #備注:截取的源碼中的一部分 

示例site對象時,會生成一個self._registry={}這個對象屬性,如果我們沒有指定admin_class,那么admin_class就是ModelAdmin,由此可以看出,admin_class是admin提供給我們定制頁面的一個自定義類,這個類必須繼承ModelAdmin這個類,以下是:

class ModelAdmin(BaseModelAdmin):
 "Encapsulates all admin options and functionality for a given model."

 list_display = ('__str__',)
 list_display_links = ()
 list_filter = ()
 list_select_related = False
 list_per_page = 100
 list_max_show_all = 200
 list_editable = ()
 search_fields = ()
 date_hierarchy = None
 save_as = False
 save_as_continue = True
 save_on_top = False
 paginator = Paginator
 preserve_filters = True
 inlines = []

 # Custom templates (designed to be over-ridden in subclasses)
 add_form_template = None
 change_form_template = None
 change_list_template = None
 delete_confirmation_template = None
 delete_selected_confirmation_template = None
 object_history_template = None
 popup_response_template = None

 # Actions
 actions = []
 action_form = helpers.ActionForm
 actions_on_top = True
 actions_on_bottom = False
 actions_selection_counter = True
 checks_class = ModelAdminChecks

 def __init__(self, model, admin_site):
 self.model = model
 self.opts = model._meta
 self.admin_site = admin_site
 super(ModelAdmin, self).__init__()

 def __str__(self):
 return "%s.%s" % (self.model._meta.app_label, self.__class__.__name__)

所以不管有沒有自定制樣式類,都會執(zhí)行self._registry[model] = admin_class(model, self),也就是說,注冊一個模型類,就會在對象的_registry這個字典中添加一個鍵值對,這個鍵是我們注冊的這個模型類 model,值是繼承ModelAdmin的樣式類或者ModelAdmin這個類的一個對象。

3,設計url

因為site是一個單例對象,所以admin在執(zhí)行完所有admin.py文件后,就會得到整個全局的一個包含所有注冊模型的字典_registry,得到這個self._registry(也就是admin.site對象)字典,我們可以for循環(huán)這個admin.site._registry字典,得到這些鍵值對,那么得到這些鍵值對有什么用呢?這就是admin設計url時會用到的。

我們訪問admin這個后臺管理頁面會發(fā)現(xiàn),這個頁面關于我們注冊的所有模型都會實現(xiàn)增刪改查功能,每個功能界面對應不同的模型類時,除了數(shù)據(jù)不同外,是一樣的,也就是說,admin對于不同的模型類用到是一套url,一套模板,那么這個url是怎么設計的呢?

我們分別訪問不同的模型類的這四個功能頁面,會發(fā)現(xiàn)一個規(guī)律:

查詢頁面url: http://IP:PORT/admin/app名/模型類的名字(全部小寫)/

添加頁面url:   http://IP:PORT/admin/app名/模型類的名字(全部小寫)/add

編輯頁面url:http://IP:PORT/admin/app名/模型類的名字(全部小寫)/id值/change

刪除頁面url:http://IP:PORT/admin/app名/模型類的名字(全部小寫)/id值/delete

通過這個規(guī)律可以看出url分發(fā)的實現(xiàn)

但是在這個實現(xiàn)的過程中,我們有一個需要注意的時,用戶訪問的請求攜帶的路徑是一個字符串的類型,我們可以通過request.path得到用戶訪問的路徑,也就能得到用戶訪問的是哪個APP下的哪個模型類,但是這兩個參數(shù)都是字符串的類型,如何通過字符串得到用戶訪問的哪張表,這是個麻煩,這時,可能我們會想到使用importlib模塊來得到這個類,但是,這樣這個過程很麻煩,Django為我們封裝好了相應的方法:我們可以通過這個模型類的類名,通過._meta.model_name這個方法得到對應的字符串形式的類名,同樣的我們也可以通過這個類名._meta.app_label得到字符串格式的相應的APP名

# 使用model代指模型類的類名
model._meta.model_name #得到字符串格式的類名(全小寫的)
model._meta.app_label #可以得到當前類所在APP的字符串的名字
# 補充
model._meta.get_field("字符串格式的字段屬性") # 得到一個字段屬性的對象field_obj,這樣我們就可以利用這個字段對象取得屬性                           # 比如: field_obj.verbose_name 

通過這兩個封裝的方法,就完美的解決了我們頭疼的問題

from django.conf.urls import url

from django.contrib import admin

def get_urls_operate():
 emp = []
 emp.append(url(r'^$',查詢頁面的視圖函數(shù)))
 emp.append(url(r'^add/$',添加頁面的視圖函數(shù)))
 emp.append(url(r'^(\d+)/change/$',編輯頁面的視圖函數(shù)))
 emp.append(url(r'^(\d+)/delete/$',刪除頁面的視圖函數(shù)))
 return emp


def get_urls():
 temp = []
 for model,main_class_obj in admin.site._registry.items():
 app_name = model._meta.app_label
 model_name = model._meta.model_name
 temp.append(url(r'^{}/{}/'.format(app_name,model_name),(get_urls_operate(),None,None))) #實現(xiàn)第二層路由的分發(fā)
 return temp

urlpatterns = [
 url(r'^Xadmin/',(get_urls(),None,None)) #自定義一個前綴 實現(xiàn)第一層路由的分發(fā)
]

這樣我們就實現(xiàn)一個通過一個路由實現(xiàn)不同場景的分發(fā)

通過這三部分,我們可以按照admin的實現(xiàn)方式,來自定制Xadmin

我們了解了admin內(nèi)部的實現(xiàn)流程,我們可以將這個實現(xiàn)過程封裝到一個類中。

  我們自定制Xadmin時,也要按照admin的流程實現(xiàn),首先是啟動項,admin中,Django啟動時,會自動的執(zhí)行每個app下的admin.py文件,我們可以自定制為啟動時,自動執(zhí)行app下的每個自定制的.py文件,比如Xadmin.py 文件,那么如何達到Django啟動的時候幫我們自動掃描加載我們自定制的Xadmin.py文件呢?這是個問題

  我們觀察可以發(fā)現(xiàn),Django在啟動時,會加載配置文件settings.py ,在settings.py文件中,有一個INSTALLED_APPS這個列表,這個列表中,放置著我們在Django項目中的所有app的配置信息,我們觀察這個列表:我們自己開啟的APP,在設置配置信息時,會在APP名字后加一個.apps.(app名首字母大寫)Config這個東西,而對應的在我們的app下,Django會給我們自動的配置一個apps.py文件,那么這個apps.py文件有什么作用呢,我們打開這個apps.py文件,看看里面的配置信息:

以blogs這個APP為例:

from django.apps import AppConfig
class BlogsConfig(AppConfig):
 name = 'blogs'

我們可以發(fā)現(xiàn),里面定義了一個類,這個類的類名就是settings配置信息中apps后面跟的那個東東,這個類中有一個靜態(tài)屬性name是當前的APP名,這個類繼承了AppConfig這個類。這就是我們從這個.py文件中所能得的所有東西,乍一看,沒有什么有用的信息,那么我們只能從它繼承的類中找了

MODELS_MODULE_NAME = 'models'
class AppConfig(object):
 """
 Class representing a Django application and its configuration.
 """
 def __init__(self, app_name, app_module):
 # Full Python path to the application eg. 'django.contrib.admin'.
 self.name = app_name

 def ready(self):
 """
 Override this method in subclasses to run code when Django starts.
    #這句話的語義為:在子類中重寫此方法,以便在Django啟動時運行代碼
 """

查看整個AppConfig,我們可以把我們的要啟動的代碼放置在重寫的ready方法中即可

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.py文件

這樣,我們就完成了自定制Xadmin的啟動階段,啟動后我們就要進行下一步注冊

 在每個app下的Xadmin.py 文件中注冊模型

以blogs這個APP下的UserInfo、Book為例:

from blogs import models
from Xadmin.service.Xadmin import site
site.register(models.UserInfo)
site.register(models.Book)

 

接下了就是設計url了,我們可以仿照admin的方式,在單例對象admin.site的這個類中封裝好這些方法

from django.conf.urls import url
from django.shortcuts import HttpResponse,render
class ModelXadmin(object):
 def __init__(self,model,site):
  self.model = model
  self.site = site
 def show(self,request):
  data_list = self.model.objects.all()
  return render(request,'show.html',locals()) #locals() 請函數(shù)內(nèi)部所有的鍵值對存儲 == {"data_list":data_list}
 def add(self,request):
  return HttpResponse('添加頁面')
 def edit(self,request, pk):
  return HttpResponse('編輯頁面')
 def delete(self,request, pk):
  return HttpResponse('刪除頁面')
 @property
 def get_urls_operate(self):
  emp = []
  emp.append(url(r'^$', self.show))
  emp.append(url(r'^add/$', self.add))
  emp.append(url(r'^(\d+)/change/$', self.edit))
  emp.append(url(r'^(\d+)/delete/$', self.delete))
  return emp
 @property
 def urls(self):
  return self.get_urls_operate,None,None
class XadminSite(object):
 def __init__(self,name='xadmin'):
  self._registry = {}
 def register(self,model,class_main=None,**option):
  if not class_main:
   class_main = ModelXadmin
  self._registry[model] = class_main(model,self)
 @property
 def get_urls(self):
  # print(admin.site._registry)
  temp = []
  for model, model_admin_object in self._registry.items():
   model_name = model._meta.model_name
   model_app = model._meta.app_label
   temp.append(url(r'^{}/{}/'.format(model_app, model_name), model_admin_object.urls))
  return temp
 @property
 def urls(self):
  return self.get_urls,None,None
site = XadminSite()

 備注:一個關鍵點,為什么把第二層分發(fā)設置在了ModelXadmin這個類中,那肯定是放在這個類中能有什么好處,如果我們把這個二級分發(fā)放在XadminSite中,那么我們要取得每一個模型的數(shù)據(jù)是很麻煩的,但是,如果我們把這個放在ModelXadmin中,由于,在register(注冊)時,我們給class_admin(XadminSite)傳了每一個模型類,所以放在這個類中,我們可以通過self.model這個屬性獲得每個模型類的數(shù)據(jù)(self.model.objects.all()),這樣就很容易得到這個模型表。

總結(jié)

以上所述是小編給大家介紹的Django中自定義admin Xadmin的實現(xiàn)代碼 ,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!
如果你覺得本文對你有幫助,歡迎轉(zhuǎn)載,煩請注明出處,謝謝!

相關文章

  • 安裝pytorch時報sslerror錯誤的解決方案

    安裝pytorch時報sslerror錯誤的解決方案

    這篇文章主要介紹了安裝pytorch時報sslerror錯誤的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-05-05
  • Python 使用pandas實現(xiàn)查詢和統(tǒng)計示例詳解

    Python 使用pandas實現(xiàn)查詢和統(tǒng)計示例詳解

    這篇文章主要為大家介紹了Python 使用pandas實現(xiàn)查詢和統(tǒng)計示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-08-08
  • python實現(xiàn)word文檔批量轉(zhuǎn)成自定義格式的excel文檔的思路及實例代碼

    python實現(xiàn)word文檔批量轉(zhuǎn)成自定義格式的excel文檔的思路及實例代碼

    這篇文章主要介紹了python實現(xiàn)word文檔批量轉(zhuǎn)成自定義格式的excel文檔的解決思路及實例代碼,代碼簡單易懂,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-02-02
  • Python中字典的setdefault()方法教程

    Python中字典的setdefault()方法教程

    在學習python字典操作方法時,感覺setdefault()方法,比字典的其它基本操作方法更難理解的同學比較多,所以想著總結(jié)以下,下面這篇文章主要給大家介紹了Python中字典的setdefault()方法,需要的朋友可以參考借鑒,下面來一起看看吧。
    2017-02-02
  • Python字符串通過''+''和join函數(shù)拼接新字符串的性能測試比較

    Python字符串通過''+''和join函數(shù)拼接新字符串的性能測試比較

    今天小編就為大家分享一篇關于Python字符串通過'+'和join函數(shù)拼接新字符串的性能測試比較,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-03-03
  • 在pandas多重索引multiIndex中選定指定索引的行方法

    在pandas多重索引multiIndex中選定指定索引的行方法

    今天小編就為大家分享一篇在pandas多重索引multiIndex中選定指定索引的行方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-11-11
  • python使用pandas讀寫excel文件的方法實例

    python使用pandas讀寫excel文件的方法實例

    pandas是一個十分強大的數(shù)據(jù)處理工具,最近需要處理數(shù)據(jù)并輸入到excel,簡單列舉它的用法,這篇文章主要給大家介紹了關于python使用pandas讀寫excel文件的相關資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-08-08
  • 關于Python中浮點數(shù)精度處理的技巧總結(jié)

    關于Python中浮點數(shù)精度處理的技巧總結(jié)

    雙精度浮點數(shù)(double)是計算機使用的一種數(shù)據(jù)類型,使用 64 位(8字節(jié)) 來存儲一個浮點數(shù)。下面這篇文章主要給大家總結(jié)介紹了關于Python中浮點數(shù)精度處理的技巧,需要的朋友可以參考借鑒,下面來一起看看吧。
    2017-08-08
  • 在Python中字典按值排序的實現(xiàn)方法

    在Python中字典按值排序的實現(xiàn)方法

    這篇文章主要介紹了在Python中字典按值排序的實現(xiàn)方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-11-11
  • Matplotlib繪圖基礎之地圖繪制詳解

    Matplotlib繪圖基礎之地圖繪制詳解

    如果分析的數(shù)據(jù)與地域相關,那么,把分析結(jié)果結(jié)合地圖一起展示的話,會讓可視化的效果得到極大的提升,下面就來講講如何利用Matplotlib一步步通過地圖來展示分析結(jié)果吧
    2023-08-08

最新評論

富阳市| 连山| 玉林市| 南乐县| 临沭县| 德格县| 蒙阴县| 长阳| 磐安县| 甘泉县| 金沙县| 南靖县| 京山县| 金塔县| 三河市| 东宁县| 德江县| 名山县| 栖霞市| 淮阳县| 慈溪市| 济宁市| 名山县| 黔西县| 宁海县| 潮安县| 察雅县| 云和县| 阿拉善右旗| 安顺市| 北碚区| 土默特右旗| 德保县| 全州县| 白朗县| 汽车| 滕州市| 叶城县| 启东市| 喀喇沁旗| 彰武县|