Openstack -- Horizon二次开发(一)

Horizon二次开发

Openstack官网上给出了一个Horizon二次开发是示例:
http://docs.openstack.org/developer/horizon/tutorials/dashboard.html
可以按照官网上示例逐步进行,完成一个自己开发的dashboard。对mypanel中的views.py代码稍作修改:

class IndexView(tabs.TabbedTableView):  
    tab_group_class = mydashboard_tabs.MypanelTabs  
    template_name = 'mydashboard/mypanel/index.html'  

    def get_context_data(self, **kwargs):
        context = super(IndexView, self).get_context_data(**kwargs)
        context['content'] = 'test code'

        return context

和Django中通用试图类似,这样就可以往前端传递content参数。
值得注意的是:

class InstanceTab(tabs.TableTab): 
    table_classes = (tables.InstancesTable,) 

    def get_instances_data(self):
        pass 

方法get_instances_data定义是用来获取表的tab数据,此方法定义必须遵从get_{{ table_name }}_data的方式,table_name就是InstancesTable的Meta中name,在官网:
http://docs.openstack.org/developer/horizon/ref/tabs.html 中有介绍。

TabbedTableView视图从tables.MultiTableMixin, TabView继承来,在MultiTableMixin基类中定义了get_tables方法如下:

def get_tables(self):
        if not self.table_classes:
            raise AttributeError('You must specify one or more DataTable '
                                 'classes for the "table_classes" attribute '
                                 'on %s.' % self.__class__.__name__)
        if not self._tables:
            for table in self.table_classes:
                if not has_permissions(self.request.user,
                                       table._meta):
                    continue
                func_name = "get_%s_table" % table._meta.name #此处就是自定的 get_instances_data 方法绑定处
                table_func = getattr(self, func_name, None)
                if table_func is None:
                    tbl = table(self.request, **self.kwargs)
                else:
                    tbl = table_func(self, self.request, **self.kwargs)
                self._tables[table._meta.name] = tbl
        return self._tables

实际结果:
mydashboard-mypanel

DataTableView

官网上给出了通用视图DataTableView的介绍:
http://docs.openstack.org/developer/horizon/topics/tables.html

DataTableView使用三要素:

  • table_class,需要新建的表的名称
  • template_name,显示模板
  • get_data(), 获取数据方法

用户可以通过实现这三者轻松实现数据表格显示。

类似于上面新建一个datatable panel,目录结构如下:
datatable
├── __init__.py
├── panel.py
├── tables.py
├── templates
│ └── datatable
│ └── index.html
├── tests.py
├── urls.py
└── views.py
其中tables.py内容与mypanel/tables.py中一样,views.py内容如下:

from horizon import tables, exceptions
from tables import InstancesTable
from openstack_dashboard import api


class IndexView(tables.DataTableView):
    table_class = InstancesTable
    template_name = 'mydashboard/datatable/index.html'

    def get_data(self, *args, **kwargs):
        try:  
            marker = self.request.GET.get(  
                        InstancesTable._meta.pagination_param, None)  

            instances,self._has_more = api.nova.server_list(  
                self.request,  
                search_opts = {'marker': marker,'paginate': True})
            if self.request.GET.get('filter', False):
                instances = [i for i in instances if self.request.GET['filter'] in i.name]
            return instances  
        except Exception:  
            self._has_more = False  
            error_message = _('Unable to get instances')  
            exceptions.handle(self.request, error_message)  

            return []  

模板mydashboard/datatable/index.html:

{% extends 'base.html' %}
{% load i18n %}
{% block title %}{% trans "Datatable" %}{% endblock %}

{% block page_header %}
  {% include "horizon/common/_page_header.html" with title=_("Datatable") %}
{% endblock page_header %}

{% block main %}
<div class="row">
   <div class="col-sm-12 datable">
   {{ table.render }}
   </div>
</div>
{% endblock %}

实际结果:
这里写图片描述

MultiTableView

http://docs.openstack.org/developer/horizon/ref/tables.html
视图MultiTableView与DataTableView很类似,不同之处在于一个页面中显示多个表,实现上也有不同,MultiTableView使用三要素:

  • table_classes,需要新建的表的名称赋值为一个tuple
  • template_name,显示模板
  • get_{{ table_name }}_data(), 为每个表定义出获取数据方法

类似于上面新建一个multidatatable panel,目录结构如下:
multidatatable
├── init.py
├── panel.py
├── tables.py
├── templates
│ └── multidatatable
│ └── index.html
├── tests.py
├── urls.py
└── views.py

表定义文件tables.py文件中内容:

from django.utils.translation import ugettext_lazy as _  
from horizon import tables  

#定义两个表InstancesTable和TenantsTable

class InstancesTable(tables.DataTable):  
    name = tables.Column("name", verbose_name=_("Name"))  
    created = tables.Column("created", verbose_name=_("Created"))
    instance_name = tables.Column("OS-EXT-SRV-ATTR:instance_name", 
                                  verbose_name=_("Instance Name"))
    zone = tables.Column('availability_zone', 
                         verbose_name=_("Availability Zone"))  
    image_name = tables.Column('image_name', verbose_name=_("Image Name")) 

    class Meta:   
        name = "instances"  
        verbose_name = _("Instances")  


class TenantsTable(tables.DataTable):
    name = tables.Column('name', verbose_name=_('Name'))
    id = tables.Column('id', verbose_name=_('Project ID'))
    enabled = tables.Column('enabled', verbose_name=_('Enabled'))

    class Meta:   
        name = "tenants"  
        verbose_name = _("Tenants") 

views.py中内容:

from horizon import tables, exceptions
from tables import InstancesTable, TenantsTable

from openstack_dashboard import policy
from openstack_dashboard import api
from horizon import messages

#分别实现获取数据方法get_instances_data和get_tenants_data
class IndexView(tables.MultiTableView):
    table_classes = (InstancesTable, TenantsTable)
    template_name = 'mydashboard/multidatatable/index.html'

    def get_instances_data(self, *args, **kwargs):
        try:  
            marker = self.request.GET.get(  
                        InstancesTable._meta.pagination_param, None)  

            instances,self._has_more = api.nova.server_list(  
                self.request,  
                search_opts = {'marker': marker,'paginate': True})
            if self.request.GET.get('filter', False):
                instances = [i for i in instances if self.request.GET['filter'] in i.name]
            return instances  
        except Exception:  
            self._has_more = False  
            error_message = _('Unable to get instances')  
            exceptions.handle(self.request, error_message)  

            return []


    def get_tenants_data(self, *args, **kwargs):  
        tenants = []
        marker = self.request.GET.get(
            TenantsTable._meta.pagination_param, None)

        self._more = False

        if policy.check((("identity", "identity:list_projects"),),
                        self.request):
            domain_context = api.keystone.get_effective_domain_id(self.request)
            try:
                tenants, self._more = api.keystone.tenant_list(
                    self.request,
                    domain=domain_context,
                    paginate=True,
                    marker=marker)
            except Exception:
                exceptions.handle(self.request,
                                  _("Unable to retrieve project list."))
        elif policy.check((("identity", "identity:list_user_projects"),),
                          self.request):
            try:
                tenants, self._more = api.keystone.tenant_list(
                    self.request,
                    user=self.request.user.id,
                    paginate=True,
                    marker=marker,
                    admin=False)
            except Exception:
                exceptions.handle(self.request,
                                  _("Unable to retrieve project information."))
        else:
            msg = \
                _("Insufficient privilege level to view project information.")
            messages.info(self.request, msg)
        if api.keystone.VERSIONS.active >= 3:
            domain_lookup = api.keystone.domain_lookup(self.request)
            for t in tenants:
                t.domain_name = domain_lookup.get(t.domain_id)
        return tenants

前端模板不是用{{ table.render }}取而代之是{{ {table_name}_table.render }}标签,示例如下:

{% extends 'base.html' %}
{% load i18n %}
{% block title %}{% trans "Multidatatable" %}{% endblock %}

{% block page_header %}
  {% include "horizon/common/_page_header.html" with title=_("Multidatatable") %}
{% endblock page_header %}

{% block main %}
<div class="row">
   <div class="col-sm-12 multitable">
   {{ instances_table.render }}
   </div>
   <div class="col-sm-12 multitable">
   {{ tenants_table.render }}
   </div>
</div>
{% endblock %}

实际效果:
这里写图片描述

Horizon中dashboard开发是一种注册的理念,新建dashboard mydashboard在enable中配置添加mydashboard,再在新建的mydashboard中新建panel,并且在mydashboard.dashboard.py文件中注册panel。

  • 2
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
学习要求: 熟悉基本的linux命令 具备基本的网络知识 掌握一门编程语言 课程特点: 深刻理解:OpenStack的设计原理,体系构架和关键技术,构建一个OpenStack环境所需的核心组件以及核心组件间的联系; 全面掌握:如何通过不同的部署工具比如packstack,部署OpenStack环境;如何通过单独部署OpenStack核心组件逐渐搭建出OpenStack环境; 定制研发:在学习openstack源码级深度解析培训后,你能了解openstack源码的体系结构,并能根据需要进行定制开发,满足您在实际生产环境中OpenStack的各种疑问和不满足的功能。 ------------------------课程内容------------------------ 课时1、课前学习环境准备 课时2、课程介绍 课时3、OpenStack概论 课时4、实例:OpenStack自动安装(Fuel) 课时5、作业:OpenStack Fuel 课时6、OpenStack安装部署答问 课时7、Keystone 详解 课时8、实例:OpenStack 手动安装 - 环境准 课时9、实例:Keystone 手动安装 课时10、实例:Keystone CLI 使用 课时11、实例:Keystone API使用 课时12、Glance详解 课时13、实例:Glance手动安装以及CLI、API 课时14、实例:Glance镜像制作 课时15、实例:Glance镜像修改 课时16、作业:Keystone手动练习 课时17、Keystone答问 课时18、作业:Glance手动练习 课时19、Nova架构及原理详解 课时20、实例:Nova手动安装 课时21、实例:Instance启动过程回顾 课时22、网络基础知识盘点 课时23、Neutron原理详解 课时24、实例:Neutron手动安装 课时25、实例:网络命名空间 课时26、实例:物理机连接openvswitch的虚 课时27、实例:租户私有网络创建 课时28、Neutron SDN 实现详解 课时29、实例:Neutron SDN 手动实现 课时30、作业:Nova、Neuron手动安装练习 课时31、作业:Neutron 相关实例练习 课时32、Neutron 答问 课时33、Cinder 原理详解 课时34、Cinder iSCSI实现原理详解 课时35、实例:Cinder 手动安装 课时36、Swift 架构与原理详解 课时37、实例:Swift 手动安装 课时38、Dashboard 介绍与演示 课时39、实例:Dashboard 手动安装 课时40、实例:Dashboard 浮动IP访问实例 课时41、实例:Dashboard 块存储的使用 课时42、实例:Dashboard 对象存储的使用 课时43、实例:OpenStack 命令行接口使用 课时44、OpenStack HA与性能调优 课时45、OpenStack Devstack 自动安 课时46、配置 OpenStack Eclipse 开发环境 课时47、配置 OpenStack Eclipse 开发环境 课时48、OpenStack 自动化测试 - 单元测试 课时49、OpenStack 自动化测试 - 集成测试 课时50、Nova 源码结构 课时51、Nova 调用流程源码解析 课时52、Nova 分层架构与业务模型剖析 课时53、Nova 自定义 API 扩展编码实现 课时54、Django 介绍与快速开始 课时55、Django view 和 urls 的用法 课时56、Django Templates 模板的用法(一) 课时57、Django Templates 模板的用法(二) 课时58、Django Form 表单的用法 课时59、Horizon 结构源码剖析(1) 课时60、Horizon 自定义 Panel 编码实现 课时61、Horizon 自定义 DataView 编码实 课时62、企业部署案例:企业私有云规划与案 课时63、OpenStack 和其他开源云平台比较

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值