真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

Django中自定義adminXadmin的實(shí)現(xiàn)-創(chuàng)新互聯(lián)

本篇文章為大家展示了Django中自定義admin Xadmin的實(shí)現(xiàn),內(nèi)容簡(jiǎn)明扼要并且容易理解,絕對(duì)能使你眼前一亮,通過(guò)這篇文章的詳細(xì)介紹希望你能有所收獲。

創(chuàng)新互聯(lián)建站服務(wù)項(xiàng)目包括管城網(wǎng)站建設(shè)、管城網(wǎng)站制作、管城網(wǎng)頁(yè)制作以及管城網(wǎng)絡(luò)營(yíng)銷策劃等。多年來(lái),我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢(shì)、行業(yè)經(jīng)驗(yàn)、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機(jī)構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,管城網(wǎng)站推廣取得了明顯的社會(huì)效益與經(jīng)濟(jì)效益。目前,我們服務(wù)的客戶以成都為中心已經(jīng)輻射到管城省份的部分城市,未來(lái)相信會(huì)繼續(xù)擴(kuò)大服務(wù)區(qū)域并繼續(xù)獲得客戶的支持與信任!

1,啟動(dòng)

我們可以通過(guò)from django.contrib import admin來(lái)看admin是如何啟動(dòng)的

Django啟動(dòng)后,會(huì)在manage.py文件中加載配置文件settings.py  ,在settings.py中有一個(gè)INSTALLED_APPS這個(gè)配置項(xiàng),Django會(huì)按照配置項(xiàng)的內(nèi)容一次加載每一個(gè)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時(shí),會(huì)加載admin相關(guān)的,我們點(diǎn)擊admin,進(jìn)入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這個(gè)接口,會(huì)自動(dòng)的加載所有APP中的admin.py這個(gè)文件,這就是admin的啟動(dòng)文件

2,注冊(cè)

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

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

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

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
 # 關(guān)于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對(duì)象時(shí),會(huì)生成一個(gè)self._registry={}這個(gè)對(duì)象屬性,如果我們沒(méi)有指定admin_class,那么admin_class就是ModelAdmin,由此可以看出,admin_class是admin提供給我們定制頁(yè)面的一個(gè)自定義類,這個(gè)類必須繼承ModelAdmin這個(gè)類,以下是:

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__)

所以不管有沒(méi)有自定制樣式類,都會(huì)執(zhí)行self._registry[model] = admin_class(model, self),也就是說(shuō),注冊(cè)一個(gè)模型類,就會(huì)在對(duì)象的_registry這個(gè)字典中添加一個(gè)鍵值對(duì),這個(gè)鍵是我們注冊(cè)的這個(gè)模型類 model,值是繼承ModelAdmin的樣式類或者M(jìn)odelAdmin這個(gè)類的一個(gè)對(duì)象。

3,設(shè)計(jì)url

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

我們?cè)L問(wèn)admin這個(gè)后臺(tái)管理頁(yè)面會(huì)發(fā)現(xiàn),這個(gè)頁(yè)面關(guān)于我們注冊(cè)的所有模型都會(huì)實(shí)現(xiàn)增刪改查功能,每個(gè)功能界面對(duì)應(yīng)不同的模型類時(shí),除了數(shù)據(jù)不同外,是一樣的,也就是說(shuō),admin對(duì)于不同的模型類用到是一套u(yù)rl,一套模板,那么這個(gè)url是怎么設(shè)計(jì)的呢?

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

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

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

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

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

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

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

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

通過(guò)這兩個(gè)封裝的方法,就完美的解決了我們頭疼的問(wèn)題

from django.conf.urls import url

from django.contrib import admin

def get_urls_operate():
 emp = []
 emp.append(url(r'^$',查詢頁(yè)面的視圖函數(shù)))
 emp.append(url(r'^add/$',添加頁(yè)面的視圖函數(shù)))
 emp.append(url(r'^(\d+)/change/$',編輯頁(yè)面的視圖函數(shù)))
 emp.append(url(r'^(\d+)/delete/$',刪除頁(yè)面的視圖函數(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))) #實(shí)現(xiàn)第二層路由的分發(fā)
 return temp

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

這樣我們就實(shí)現(xiàn)一個(gè)通過(guò)一個(gè)路由實(shí)現(xiàn)不同場(chǎng)景的分發(fā)

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

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

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

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

以blogs這個(gè)APP為例:

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

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

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.
    #這句話的語(yǔ)義為:在子類中重寫此方法,以便在Django啟動(dòng)時(shí)運(yùn)行代碼
 """

查看整個(gè)AppConfig,我們可以把我們的要啟動(dòng)的代碼放置在重寫的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啟動(dòng)時(shí)會(huì)自動(dòng)掃描每個(gè)app下的Xadmin.py文件

這樣,我們就完成了自定制Xadmin的啟動(dòng)階段,啟動(dòng)后我們就要進(jìn)行下一步注冊(cè)

 在每個(gè)app下的Xadmin.py 文件中注冊(cè)模型

以blogs這個(gè)APP下的UserInfo、Book為例:

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

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

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() 請(qǐng)函數(shù)內(nèi)部所有的鍵值對(duì)存儲(chǔ) == {"data_list":data_list}
 def add(self,request):
  return HttpResponse('添加頁(yè)面')
 def edit(self,request, pk):
  return HttpResponse('編輯頁(yè)面')
 def delete(self,request, pk):
  return HttpResponse('刪除頁(yè)面')
 @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()

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

上述內(nèi)容就是Django中自定義admin Xadmin的實(shí)現(xiàn),你們學(xué)到知識(shí)或技能了嗎?如果還想學(xué)到更多技能或者豐富自己的知識(shí)儲(chǔ)備,歡迎關(guān)注創(chuàng)新互聯(lián)成都網(wǎng)站設(shè)計(jì)公司行業(yè)資訊頻道。

另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無(wú)理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國(guó)服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡(jiǎn)單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場(chǎng)景需求。


本文題目:Django中自定義adminXadmin的實(shí)現(xiàn)-創(chuàng)新互聯(lián)
網(wǎng)站地址:http://weahome.cn/article/dceeco.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部