Openstack--Horizon二次開発(一)

17802 ワード

ホリゾン二次開発
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に紹介されています.
TabbedTableビューは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

実績:Openstack -- Horizon二次开发(一)_第1张图片
DataTableView
公式サイトには、汎用ビューDataTable Viewの紹介があります.http://docs.openstack.org/developer/horizon/topics/tables.html
DataTable Viewでは、次の3つの要素を使用します.
  • table_class、新規テーブルの名前
  • が必要です
  • template_name、表示テンプレート
  • get_data()、データ取得方法
  • ユーザーは、この3つを実装することで、データテーブルの表示を簡単に実現できます.
    上の新しいdatatable panelと同様に、ディレクトリ構造は次のとおりです.datatable├——_init__.py ├── panel.py ├── tables.py ├── templates │ └── datatable │ └── index.html ├── tests.py ├── urls.py └── views.py中tables.pyコンテンツとmypanel/tables.pyのようにviewspyの内容は次のとおりです.
    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 %}

    実績:Openstack -- Horizon二次开发(一)_第2张图片
    MultiTableView
    http://docs.openstack.org/developer/horizon/ref/tables.htmlビューMultiTableViewはDataTableViewと似ています.異なる点は、1ページに複数のテーブルが表示され、実装上も異なる点です.MultiTableViewは3つの要素を使用します.
  • 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 %}

    実績:Openstack -- Horizon二次开发(一)_第3张图片
    Horizonでのdashboardの開発は登録の理念であり、新しいdashboard mydashboardはenableでmydashboardを追加し、新しいmydashboardでpanelを新規し、mydashboard.dashboard.pyファイルにpanelを登録します.