博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
django-cms 代码研究(八)app hooks
阅读量:4928 次
发布时间:2019-06-11

本文共 4126 字,大约阅读时间需要 13 分钟。

app钩子,啥玩意呢?

就是把现有的app,集成到cms的一种手段。

有两种实现方式:

1) 定义cms_app.py,如下:

from cms.app_base import CMSAppfrom cms.apphook_pool import apphook_poolfrom django.utils.translation import ugettext_lazy as _class MyApphook(CMSApp):    name = _("My Apphook")    urls = ["myapp.urls"]apphook_pool.register(MyApphook)

官方文档查看这里:http://docs.django-cms.org/en/latest/extending_cms/app_integration.html#app-hooks

加载逻辑,通过discover_apps的load('cms_app')来加载(前提是在settings.py中未定义 CMS_APPHOOKS):在所有的installed_app中,查找cms_app模块,并自动import_module

 

2) 在setting.py中定义CMS_APPHOOKS

APPHOOKS=('yourmodule.you_object1','yourmodule.you_object2',...)

这是从源码中分析的来的,如下:

C:\Python27\Lib\site-packages\django_cms-3.0.3-py2.7.egg\cms\apphook_pool.py (45~57)

def discover_apps(self):        self.apphooks = get_cms_setting('APPHOOKS')        if self.apphooks:            for cls in iterload_objects(self.apphooks):                try:                    self.register(cls, discovering_apps=True)                except AppAlreadyRegistered:                    pass        else:            load('cms_app')        self.discovered = True

iterload_objects,是一个生成器,如下:

def iterload_objects(import_paths):    """    Load a list of objects.    """    for import_path in import_paths:        yield load_object(import_path)

load_object

def load_object(import_path):    if '.' not in import_path:        raise TypeError(            "'import_path' argument to 'django_load.core.load_object' must "            "contain at least one dot."        )    module_name, object_name = import_path.rsplit('.', 1)    module = import_module(module_name)    return getattr(module, object_name)

 

顺便分析下 C:\Python27\Lib\site-packages\django_cms-3.0.3-py2.7.egg\cms\apphook_pool.py的源码:

 实例变量:

def __init__(self):        self.apphooks = []        self.apps = {}        self.discovered = False

方法:clear/register/discover_apps/get_apphooks/get_apphook

其中: discover_apps上面已经分析过了。

clear,清空实例变量,如下(作者说,python不需要clear,会自动回收,这个方法该砍掉了):

def clear(self):        # TODO: remove this method, it's Python, we don't need it.        self.apphooks = []        self.apps = {}        self.discovered = False

register,用于注册app,app的基类如下:

class CMSApp(object):    name = None    urls = None    menus = []    app_name = None    permissions = True

register,本质是把app放到apphook_pool实例的apps中,不过之前会有一些验证,如下:

def register(self, app, discovering_apps=False):        if self.apphooks and not discovering_apps:            return        if app.__name__ in self.apps:            raise AppAlreadyRegistered(                'A CMS application %r is already registered' % app.__name__)        if not issubclass(app, CMSApp):            raise ImproperlyConfigured(                'CMS application must inherit from cms.app_base.CMSApp, '                'but %r does not' % app.__name__)        if not hasattr(app, 'menus') and hasattr(app, 'menu'):            warnings.warn("You define a 'menu' attribute on CMS application %r, "                "but the 'menus' attribute is empty, did you make a typo?" % app.__name__)        self.apps[app.__name__] = app

其干活的代码只有最后一句:

self.apps[app.__name__] = app

get_apphooks, 返回一个列表 [(app,app.name)....],并按照app.name排序,如下:

def get_apphooks(self):        hooks = []        if not self.discovered:            self.discover_apps()        for app_name in self.apps:            app = self.apps[app_name]            if app.urls:                hooks.append((app_name, app.name))        # Unfortunately, we loose the ordering since we now have a list of tuples. Let's reorder by app_name:        hooks = sorted(hooks, key=lambda hook: hook[1])        return hooks

get_apphook,根据app名字查找app,代码如下:

def get_apphook(self, app_name):        if not self.discovered:            self.discover_apps()        try:            return self.apps[app_name]        except KeyError:            # deprecated: return apphooks registered in db with urlconf name instead of apphook class name            for app in self.apps.values():                if app_name in app.urls:                    return app        raise ImproperlyConfigured('No registered apphook %r found' % app_name)

  

 

 

 

 

 

 

 

转载于:https://www.cnblogs.com/Tommy-Yu/p/3975330.html

你可能感兴趣的文章
2018-10-11
查看>>
国内NLP的那些人那些会
查看>>
ffmpeg转成h264编码格式、moov(meta数据)移动到头部、码率做一定压缩、分辨率也降下来...
查看>>
[原创]java WEB学习笔记94:Hibernate学习之路---session 的管理,Session 对象的生命周期与本地线程绑定...
查看>>
SharePoint 2010 母版页定制小思路介绍
查看>>
PHP对大小写敏感问题的处理比较乱,写代码时可能偶尔出问题,所以这里总结一下。...
查看>>
poj 3463(最短路和比最短路大1的路的数量)(dijkstra)
查看>>
苹果App Store公布最新应用审核标准:更加严格
查看>>
DbUtils类
查看>>
Vuejs开发问题总结
查看>>
JDBC request的查询结果作为下一个jdbc request的入参—简单
查看>>
自动化测试页面元素被遮挡
查看>>
CRM(2)
查看>>
JavaScript Number() Vs new Number()
查看>>
【最小生成树】畅通工程
查看>>
【最短路径】畅通工程续
查看>>
基于mpvue的小程序项目搭建的步骤一
查看>>
python之路-Pymysql
查看>>
中断处理中的save_all、restore_all和iret
查看>>
创建 overlay 网络 - 每天5分钟玩转 Docker 容器技术(50)
查看>>