简体   繁体   中英

how to override handle method in SelfHandlingForm in OpenStack horizon?

I want to add some more data to properties of CreateImageForm in handle method. So when it create image, it has one custom property abc .

After changes code might be like this

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.')) 

I want to do this without changing existing code, like overriding or inheriting class.

No override way without touching any code .

from ModalFormView in horizon/forms/views.py
You can see that form_valid method uses form.handle(...) .

So this handle method is HARD CODED in Horizon.

At least , you have to touch one place to override handle without directly modifying 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!
    ...

Maybe you want to override it because you are afraid of the conflict when upgrading Horizon in future.

If you want to customize Horizon and don't touch any thing, the best way is:

  1. Create a your dashborad(tab)
  2. Add your panel. In your panel, you can easily inherit any classes you want from Project/Admin, and change the part you want to. Add logic, add form elements, add anything...

Finally, in your case, you just want to add ONE line into code, so why not just add it? If you upgrade your Horizon, I don't think that this part will cause a conflict.

You can add any overrides you want using the customization_module in HORIZON_CONFIG. Just add the path to your file containing the overrides like so:

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

In the overrides.py file that you created you can add a monkey patch to override an existing class with your new class:

class YourCreateImageForm(CreateImageForm):
    ...


form_class = project_forms.YourCreateImageForm

It's basically the same idea mentioned in the above comment but you can avoid touching upstream code using the customization_module.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM