python独有的特性引入模块后会执行一次模块的内容,并且生成pyc文件把引入的模块添加到pyc文件中,下次其他模块再调用相同的模块内容时会从pyc文件中读取不会重新执行并生成新的对象,这是python独有的一种单例模式!
django的admin.site就是用这种模式生成的单例对象,它贯穿django全局只要是在同一个程序下调用的admin.site都是同一个对象,使用admin.site.register注册的所有表名都会添加到一个以类对象为键,model_admin为值的字典中.
django中get_url源码:
def get_urls(self):
from django.urls import include, path, re_path
# 由于这个模块在应用程序的根包中导入
# 它不能从模块级的其他应用程序导入模型,
# and django.contrib.contenttypes.views imports ContentType.
from django.contrib.contenttypes import views as contenttype_views
def wrap(view, cacheable=False):
def wrapper(*args, **kwargs):
return self.admin_view(view, cacheable)(*args, **kwargs)
wrapper.admin_site = self
return update_wrapper(wrapper, view)
# Admin-site-wide views.
urlpatterns = [
path('', wrap(self.index), name='index'),
path('login/', self.login, name='login'),
path('logout/', wrap(self.logout), name='logout'),
path('password_change/', wrap(self.password_change, cacheable=True), name='password_change'),
path(
'password_change/done/',
wrap(self.password_change_done, cacheable=True),
name='password_change_done',
),
path('jsi18n/', wrap(self.i18n_javascript, cacheable=True), name='jsi18n'),
path(
'r/<int:content_type_id>/<path:object_id>/',
wrap(contenttype_views.shortcut),
name='view_on_site',
),
]
# 添加每个模型的视图,并为其创建一个有效的url列表
# app_index
valid_app_labels = []
for model, model_admin in self._registry.items():
urlpatterns += [
path('%s/%s/' % (model._meta.app_label, model._meta.model_name), include(model_admin.urls)),
]
if model._meta.app_label not in valid_app_labels:
valid_app_labels.append(model._meta.app_label)
# 如果有模型管理员注册,我们应该有一个应用列表
# 我们需要允许访问appindex视图的标签
if valid_app_labels:
regex = r'^(?P<app_label>' + '|'.join(valid_app_labels) + ')/$'
urlpatterns += [
re_path(regex, wrap(self.app_index), name='app_list'),
]
return urlpatterns
Xadmin的路由分发:
url:
path('Xadmin/', (get_urls(), None, None)),
def test1(request):
return HttpResponse("这是test1的网页")
def search(request):
return HttpResponse("这是查的页面")
def add(request):
return HttpResponse("这是增的页面")
def change(request,nid):
return HttpResponse("这是改的页面")
def delete(request,nid):
return HttpResponse("这是删的页面")
def get_urls_two():
temp=[]
temp.append(re_path(r'^$',search))
temp.append(re_path(r'^add/$', add))
temp.append(re_path(r'^(d+)/change/$', change))
temp.append(re_path(r'^(d+)/delete/$', delete))
return temp
def get_urls():
temps = []
for model,admin_class in admin.site._registry.items():
app_name = model._meta.app_label #获取app的名字
model_name = model._meta.model_name #获取admin.site.registry注册的数据库表名的字符串形式
temps.append(re_path(r'^{}/{}/'.format(app_name,model_name),(get_urls_two(),None,None))) #路由分发必须传入元组第一个参数嵌套列表
return temps