Django——admin源码分析
在Django中,如果我们新建一个项目,只要在admin.py文件中注册,就可以对其相应的文件进行增删改查操作。
而我们在路由系统中只看到了一条信息:url(r'^admin/', admin.site.urls),但是我们确实是可以进行增删改查操作?这其中到底有什么端倪了?
下面我们会从Django源码的角度来分析admin执行流程。
1.循环加载执行所有已经注册的app中的admin.py文件
def autodiscover():
autodiscover_modules('admin', register_to=site)
2.执行admin.py文件中的代码
class BookAdmin(admin.ModelAdmin):
list_display = ("title",'publishDate', 'price') admin.site.register(Book, BookAdmin)
admin.site.register(Publish)
3.admin.site

这里应用的是一个单例模式,对于AdminSite类的一个单例模式,执行的每一个app中的每一个admin.site都是一个对象。
4.执行register方法
admin.site.register(Book, BookAdmin)
admin.site.register(Publish)
register函数源码信息:
class AdminSite(object):
......
def register(self, model_or_iterable, admin_class=None, **options): if not admin_class: #如果没有设置admin_class这个类
admin_class = ModelAdmin #那么就会执行默认的样式 if isinstance(model_or_iterable, ModelBase):
model_or_iterable = [model_or_iterable]
for model in model_or_iterable: #在名称列表中循环
......(省略)
self._registry[model] = admin_class(model, self) #这句话是关键
执行完admin.site.register()代码之后,就创建_registry这个字典,表名为键,admin_class(样式)为值,我们也可以打印这个字典。
到这里,注册结束。
5.admin的URL配置
上面已经注册成功了,现在该解释URL自动生成的过程了。
我们先来分析Django源码是如何实现的,从url(r'^admin/', admin.site.urls)出发,我们可以直接找urls函数
@property
def urls(self):
return self.get_urls(), 'admin', self.name
随后我们去找get_urls()这个函数,
def get_urls(self):
from django.conf.urls import url, include 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 = [
url(r'^$', wrap(self.index), name='index'),
url(r'^login/$', self.login, name='login'),
url(r'^logout/$', wrap(self.logout), name='logout'),
url(r'^password_change/$', wrap(self.password_change, cacheable=True), name='password_change'),
url(r'^password_change/done/$', wrap(self.password_change_done, cacheable=True),
name='password_change_done'),
url(r'^jsi18n/$', wrap(self.i18n_javascript, cacheable=True), name='jsi18n'),
url(r'^r/(?P<content_type_id>\d+)/(?P<object_id>.+)/$', wrap(contenttype_views.shortcut),
name='view_on_site'),
]
关于urlpatterns是如何生成的我们不了解,只知道在这里就生成了增删改查的URL,现在我们用自己的手段来实现这一过程。
6.自定义实现admin配置
首先,需要用到路由分发,就像下面这样:
def test01(request):
return HttpResponse("test01") def test02(request):
return HttpResponse("test02") def test03(request):
return HttpResponse("test03") urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^kebi/',([
url(r'^test01/', test01),
url(r'^test02/', test02), #一条URL包含很多条内置的URL,这个部分可以封装到函数中
url(r'^test03/', test03),
],None,None))
]
里面还可以再次封装,就像这样:
def test01(request):
return HttpResponse("test01") def test0203(request):
return HttpResponse("test0203") def test0204(request):
return HttpResponse("test0204") def test05(request):
return HttpResponse("test05") urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^kebi/',([
url(r'^test01/', test01),
url(r'^test02/', ([
url(r'^test03/', test0203),
url(r'^test04/', test0204),
],None,None)),
url(r'^test05/', test05),
],None,None))
]
我们将其封装到一个函数之中:
from django.conf.urls import url
from django.contrib import admin
from django.shortcuts import HttpResponse def test01(request):
return HttpResponse("test01") def get_urls():
urlpatterns = [] for model,model_config in admin.site._registry.items():
model_name = model._meta.model_name #model可以说是类名,现在要获取字符串拼接,获取类名,属于字符串
app_label = model._meta.app_label #app名,属于字符串
urlpatterns.append(url('%s/%s'%(app_label,model_name),test01))
return urlpatterns urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^kebi/',(get_urls(),None,None)) #只要urlpatterns有值,就可以做分发
]
这样就生成了:
http://127.0.0.1:8000/kebi/app02/publish
http://127.0.0.1:8000/kebi/app01/authors
仅仅如此,还没有满足要求,那么就在做一次分发,就像这样:
from django.contrib import admin
from django.shortcuts import HttpResponse def show_list(request):
return HttpResponse("查看列表") def add_list(request):
return HttpResponse("增加列表") def change_list(request,id):
return HttpResponse("更改列表") def delete_list(request,id):
return HttpResponse("删除列表") def get_urls_func():
temp = []
#现在来写增删改查
temp.append(url('^$',show_list))
temp.append(url('/add/$',add_list))
temp.append(url('/(\d+)/change/$',change_list))
temp.append(url('/(\d+)/delete/$',delete_list)) return temp def get_urls():
urlpatterns = [] for model,model_config in admin.site._registry.items():
model_name = model._meta.model_name #model可以说是类名,现在要获取字符串拼接
app_label = model._meta.app_label #app名
urlpatterns.append(url('%s/%s'%(app_label,model_name),(get_urls_func(),None,None)))
return urlpatterns urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^kebi/',(get_urls(),None,None)) #只要urlpatterns有值,就可以做分发
]
现在能够访问的有这些:
#两个表都会自动生成增删改查的URL
http://127.0.0.1:8000/kebi/app02/publish
http://127.0.0.1:8000/kebi/app02/publish/add
http://127.0.0.1:8000/kebi/app02/publish/1/change
http://127.0.0.1:8000/kebi/app02/publish/2/delete http://127.0.0.1:8000/kebi/app01/authors
http://127.0.0.1:8000/kebi/app01/authors/add
http://127.0.0.1:8000/kebi/app01/authors/1/change
http://127.0.0.1:8000/kebi/app01/authors/2/delete
下面是效果:



Django——admin源码分析的更多相关文章
- admin源码分析
django settings 源码分析 导入settingso模块,进入源码,会发现settings是一个 单例 LazySettings类实例化产生的一个对象,LazySettings实例化后就会 ...
- $Django cbv源码分析 djangorestframework框架之APIView源码分析
1 CBV的源码分析 #视图 class login (View): pass #路由 url(r'^books/$', views.login.as_view()) #阅读源码: #左侧工程栏--- ...
- django -admin 源码解析
admin源码解析 单例模式 单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在.当你希望在整个系统中,某个类只能出现一个实例时,单 ...
- django --- DetailView源码分析
[背景] 最近在看django官方文档的class-based-views这一节的时候一直不得要领,感觉自己清楚,但是回想起来又没有脉络:于是没有办法只 能是“暗中观察”django的源码了. 刚打开 ...
- Django——Session源码分析
首先我们导入django.contrib.sessions.middleware这个中间件,查看里面的Session源码 from django.contrib.sessions.middleware ...
- Django admin源码剖析
单例模式 单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在.当你希望在整个系统中,某个类只能出现一个实例时,单例对象就能派上用场. ...
- Django之REST framework源码分析
前言: Django REST framework,是1个基于Django搭建 REST风格API的框架: 1.什么是API呢? API就是访问即可获取数据的url地址,下面是一个最简单的 Djang ...
- django Rest Framework----APIView 执行流程 APIView 源码分析
在django—CBV源码分析中,我们是分析的from django.views import View下的执行流程,这篇博客我们介绍django Rest Framework下的APIView的源码 ...
- django---APIView源码分析
django---APIView源码分析 前言:APIView基于View 看这部分内容一定要懂django-CBV里的内容 在django-CBV源码分析中,我们是分析的from django.vi ...
随机推荐
- UI-1-UI入门
课程要点: 创建一个iOS工程 AppDelegate类 UIKit框架以及UIWindow 在window上添加第一个试图UIView NSTimer(定时器) 创建一个iOS工程 PS:接下来简单 ...
- apache gzip
1.首先启动模块mod_deflate.so和mod_headers.so 2.httpd.conf #文件缓存时间配置<FilesMatch ".(flv|gif|jpg|jpeg| ...
- MII接口概念简述
MII: Medium Independent Interface 媒体独立接口,也称介质无关接口 RMII: Reduced MII 简化媒体独立接口 GMII: Gigabit Medium In ...
- hdu5800 To My Girlfriend dp 需要比较扎实的dp基础。
To My Girlfriend Time Limit: 2000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) ...
- Windows 下tomcat安装及将多个tomcat注册为Windows服务
一.应用场景 虽然Windows在当下已经不再是我们作为服务器操作系统平台的首选,但是还是有一些开发商或者项目整体需求的限制必须运行在Windows系统平台之下.为了避免多个应用部署在同一个tomca ...
- 项模板选择器属性(ItemTemplateSelector属性)和样式选择器(ItemContainerStyleSelector)
3.4.5 共享尺寸组 样式选择器: 或者========================================
- asp.net *.ashx类型的文件使用说明
你想创建一个ASP.NET文件,它不是aspx文件,它能动态的返回一个图片.XML文件或其他非HTML文件. 解决方案:使用ashx文件. 1. 使用ASHX handlers 首先,我们要回顾要使用 ...
- Python+selenium打开或关闭浏览器
Python+selenium打开或关闭浏览器 一.打开或关闭火狐浏览器 1. 初始化一个webdriver实例对象driver,然后打开和关闭firefox浏览器.要用selenium打 ...
- SET ANSI_NULLS ON 在T-SQL中是什么意思
from:https://www.cnblogs.com/kekong/p/6731321.html Transact-SQL 支持在与空值进行比较时,允许比较运算符返回 TRUE 或 FALSE. ...
- redhat 配置本地yum源163yum源epel 源,无需卸载yum!无须拷贝ISO
都知道redhat不收费,但是其yum服务是要收费的,不想出钱那就自己配置yum源就好了. 首先,博主之前也没用过redhat,第一次用yum装包的时候提示什么没注册之类的,balaba一大堆,然后就 ...