改动horizon,要增加自己的处理模块,同时又不在openstack_dashboard.api下的模块时,在api package下添加自己的module,可能会报错:
File "/home/ding/horizon/openstack_dashboard/api/__init__.py", line 34, in <module>
from openstack_dashboard.api import base
ImportError: cannot import name base
搜索之后发现是horizon自己的一个已知bug,可能和django有关,修改方法是:
修改api.__init__.py,将from openstack_dashboard.api import base 改为import base,
对其他的比如nova等也采用相同的方式
经过前两篇之后,改动code时服务会自动刷新,出现错误,django会在web页面上有trace bug的信息,根据信息调试即可,事实上,trace的信息很长很多,
一般的只有最下面的几条是和自己code相关的,点击展开Local Vars能看见变量的值, 点击出错行,可以展开上下文code情况浏览。
如何实现对table的刷新呢,我翻看源代码有发现合适的方式,如果:
class RefreshTable(tables.LinkAction):
url=xxx(index操作)
采用继承自LinkAction时,界面会混乱,显示为重叠的index的结果,即若index有三条内容,此时click RefreshTable就会有6条数据显示,
同时页面会死掉
class RefreshTable(tables.BatchAction):
success_url=xxx(index)
若继承自BatchAction,结果必须在select中选中item才可以点击batchaction,和delete一个item类似,只有勾选了item才能delete,这是
BatchAction的设计初衷。
这时,有三种方式:
1. 把BatchAction或者LinkAction拉出来,重写,综合两种action的特点写自己的Action
2.上面一种方法是可以的,但是看起来比较ugly,搞多重继承行不行呢,经过试验失败了,还是会重影
3. 还是多重继承,但是在LinkAction的url中指定一个什么都不做的url
url(r'^nosuch/$', 'do_nothing', name='nosuch'),
然后在views中:
def do_nothing(request):
blank=HttpResponse('Blank')#注意此处的HttpResponse是from django.http.response import HttpResponse
return blank
这样终于成功了。
需要指出的是在LinkAction中的方法:get_link_url中会有关于:
try:
if datum:
obj_id = self.table.get_object_id(datum)
return urlresolvers.reverse(self.url, args=(obj_id,))
else:
return urlresolvers.reverse(self.url)
except urlresolvers.NoReverseMatch as ex:
LOG.info('No reverse found for "%s": %s' % (self.url, ex))
return self.url
如果你不想在log中看到烦人的message,No reverse xxxx,可以重写get_link_url
Horizon中的url.py:
在前面的两篇中,有了Horizon的开发环境,看horizon的代码,其实只要花时间就能找出添加修改模块的固定模式,但是url中的对应关系我迷糊了一下:
比如这个网络操作的url映射中,network_id在哪里呢
url(r'^(?P<id>[^/]+)/update_metadata/$',
views.UpdateMetadataView.as_view(), name='update_metadata'),
这个id是怎么传进来的呢?
我们跟一下image update时的操作流程就明白了:
class UpdateMetadata(tables.LinkAction):
url = "horizon:admin:images:update_metadata" #根据url.py我们知道调用了上面的url,因此我们来找id
name = "update_metadata"
verbose_name = _("Update Metadata")
classes = ("ajax-modal",)
icon = "pencil"
只可能去父类LinkAction中找:
找到:from horizon.tables.actions import LinkAction # noqa
有两个操作;
1.def associate_with_table(self, table):和表关联
2.
if callable(self.url):
return self.url(datum, **self.kwargs)
try:
if datum:
obj_id = self.table.get_object_id(datum)#table会重载get_object_id方法
return urlresolvers.reverse(self.url, args=(obj_id,))
else:
return urlresolvers.reverse(self.url)
3. 若不重载就直接是id属性,若重载就可以定义自己的table中每行的id了
4.可以追的更细,又进到metaclass里面了,you can trace it,but not for normal users:)
本文介绍如何在OpenStack Horizon中定制自己的处理模块,并解决在定制过程中遇到的问题,如导入错误和表格刷新难题。通过调整代码结构和使用特定的方法,实现了自定义功能并保持系统的稳定性。
6864

被折叠的 条评论
为什么被折叠?



