Cleanup get_viewname URL resolution and make extensible #11458

Closed
opened 2025-12-29 21:45:31 +01:00 by adam · 0 comments
Owner

Originally created by @arthanson on GitHub (Aug 7, 2025).

Originally assigned to: @arthanson on GitHub.

Proposed Changes

Create a new utility function alongside get_viewname tentatively called get_action_url that combines the functionality of get_viewname and reversing the URL. Also allow this function to be overridden at the model level by plugins.

Justification

utilities.views.get_viewname is used throughout the code doing basically the following:

viewname = get_viewname(instance, 'action')
url = reverse(viewname, kwargs={'pk': instance.pk})

In almost every case the URL is the only thing needed so this code can be made DRY by a combined function.

In addition, this function requires the viewname to conform to the '{app_label}:{model_name}_{action} format with a single param being the object_id. While this is valid for most plugins and models, there are cases where the plugin would need a different format (for example a URL with extra kwargs being passed in). It would be fairly easy to make the URL resolution for this function be overridable at the model-class level, for example:

def get_action_url(model, action=None, rest_api=False, kwargs=None):
    if hasattr(model, '_get_action_url'):
        return model._get_action_url(action, rest_api, kwargs)

    return reverse(get_viewname(model, action, rest_api), kwargs=kwargs)
Originally created by @arthanson on GitHub (Aug 7, 2025). Originally assigned to: @arthanson on GitHub. ### Proposed Changes Create a new utility function alongside `get_viewname` tentatively called `get_action_url` that combines the functionality of get_viewname and reversing the URL. Also allow this function to be overridden at the model level by plugins. ### Justification `utilities.views.get_viewname` is used throughout the code doing basically the following: ``` viewname = get_viewname(instance, 'action') url = reverse(viewname, kwargs={'pk': instance.pk}) ``` In almost every case the URL is the only thing needed so this code can be made DRY by a combined function. In addition, this function requires the viewname to conform to the `'{app_label}:{model_name}_{action}` format with a single param being the object_id. While this is valid for most plugins and models, there are cases where the plugin would need a different format (for example a URL with extra kwargs being passed in). It would be fairly easy to make the URL resolution for this function be overridable at the model-class level, for example: ``` def get_action_url(model, action=None, rest_api=False, kwargs=None): if hasattr(model, '_get_action_url'): return model._get_action_url(action, rest_api, kwargs) return reverse(get_viewname(model, action, rest_api), kwargs=kwargs) ```
adam added the status: acceptedtype: housekeeping labels 2025-12-29 21:45:31 +01:00
adam closed this issue 2025-12-29 21:45:31 +01:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/netbox#11458