【问题标题】:how to override handle method in SelfHandlingForm in OpenStack horizon?如何在 OpenStack Horizo​​n 中覆盖 SelfHandlingForm 中的句柄方法?
【发布时间】:2014-09-02 03:55:26
【问题描述】:

我想在handle 方法中向CreateImageForm属性 添加更多数据。所以当它创建图像时,它有一个自定义属性abc

修改后的代码可能是这样的

def handle(self, request, data):
        # Glance does not really do anything with container_format at the
        # moment. It requires it is set to the same disk_format for the three
        # Amazon image types, otherwise it just treats them as 'bare.' As such
        # we will just set that to be that here instead of bothering the user
        # with asking them for information we can already determine.
        if data['disk_format'] in ('ami', 'aki', 'ari',):
            container_format = data['disk_format']
        else:
            container_format = 'bare'

        meta = {'is_public': data['is_public'],
                'protected': data['protected'],
                'disk_format': data['disk_format'],
                'container_format': container_format,
                'min_disk': (data['minimum_disk'] or 0),
                'min_ram': (data['minimum_ram'] or 0),
                'name': data['name'],
                'properties': {}}

        if data['description']:
            meta['properties']['description'] = data['description']
        if data['architecture']:
            meta['properties']['architecture'] = data['architecture']

        ###################################
        # My changes 
        ###################################
        meta['properties']['abc'] = 'def'

        if (settings.HORIZON_IMAGES_ALLOW_UPLOAD and
                policy.check((("image", "upload_image"),), request) and
                data.get('image_file', None)):
            meta['data'] = self.files['image_file']
        else:
            meta['copy_from'] = data['copy_from']

        try:
            image = api.glance.image_create(request, **meta)
            messages.success(request,
                _('Your image %s has been queued for creation.') %
                data['name'])
            return image
        except Exception:
            exceptions.handle(request, _('Unable to create new image.')) 

我想在不更改现有代码的情况下执行此操作,例如覆盖或继承类。

【问题讨论】:

    标签: django django-forms openstack openstack-horizon


    【解决方案1】:

    没有覆盖方式不接触任何代码

    来自ModalFormViewhorizon/forms/views.py
    可以看到form_valid 方法使用了form.handle(...)

    所以这个handle 方法在 Horizo​​n 中是硬编码的。

    至少,你必须触摸一个地方来覆盖handle而不直接修改CreateImageForm

    # openstack_dashboard/dashboards/project/images/images/forms.py
    class YourCreateImageForm(CreateImageForm): # <== Create your form inherited from CreateImageForm!
        def handle(self, request, data):
            ...
            (the whole your logic here)
            ...
    
    # openstack_dashboard/dashboards/project/images/images/views.py
    class CreateView(forms.ModalFormView):
        form_class = project_forms.YourCreateImageForm  # <== touch here!
        ...
    

    也许你想覆盖它,因为你害怕将来升级 Horizo​​n 时发生冲突。

    如果你想自定义Horizo​​​​n并且不接触任何东西,最好的方法是:

    1. 创建您的仪表板(选项卡)
    2. 添加您的面板。在您的面板中,您可以轻松地从 Project/Admin 继承您想要的任何类,并更改您想要的部分。添加逻辑,添加表单元素,添加任何东西......

    最后,在您的情况下,您只想在代码中添加一行,那么为什么不直接添加呢?如果你升级你的地平线,我认为这部分不会引起冲突。

    【讨论】:

    • 你说得对,我的担心是正确的,如果我添加新的仪表板和覆盖方法,那么它将向 Horizo​​n 添加新菜单,所以当用户点击我的菜单时,他将获得新功能,但如果他点击在旧菜单上,那么他不会得到它。
    【解决方案2】:

    您可以使用 HORIZON_CONFIG 中的自定义模块添加任何您想要的覆盖。只需将路径添加到包含覆盖的文件,如下所示:

    HORIZON_CONFIG = {
        'customization_module': 'some_path.overrides',
    }
    

    在您创建的 overrides.py 文件中,您可以添加一个猴子补丁以用您的新类覆盖现有类:

    class YourCreateImageForm(CreateImageForm):
        ...
    
    
    form_class = project_forms.YourCreateImageForm
    

    这与上面评论中提到的基本相同,但您可以避免使用自定义模块接触上游代码。

    【讨论】:

      猜你喜欢
      • 2013-11-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-12-07
      • 1970-01-01
      • 1970-01-01
      • 2021-05-17
      相关资源
      最近更新 更多