Fixes #8764: Correct view name resolution for dynamic form fields

This commit is contained in:
jeremystretch 2022-02-28 15:17:49 -05:00
parent da6ed8ea11
commit d6c272cfd6
3 changed files with 25 additions and 12 deletions

View File

@ -155,6 +155,7 @@ Where it is desired to limit the range of available VLANs within a group, users
* [#8682](https://github.com/netbox-community/netbox/issues/8682) - Limit available VLANs by group min/max VIDs * [#8682](https://github.com/netbox-community/netbox/issues/8682) - Limit available VLANs by group min/max VIDs
* [#8683](https://github.com/netbox-community/netbox/issues/8683) - Fix `ZoneInfoNotFoundError` exception under Python 3.9+ * [#8683](https://github.com/netbox-community/netbox/issues/8683) - Fix `ZoneInfoNotFoundError` exception under Python 3.9+
* [#8761](https://github.com/netbox-community/netbox/issues/8761) - Correct view name resolution under journal entry views * [#8761](https://github.com/netbox-community/netbox/issues/8761) - Correct view name resolution under journal entry views
* [#8764](https://github.com/netbox-community/netbox/issues/8764) - Correct view name resolution for dynamic form fields
### Other Changes ### Other Changes

View File

@ -5,6 +5,7 @@ from django.forms import BoundField
from django.urls import reverse from django.urls import reverse
from utilities.forms import widgets from utilities.forms import widgets
from utilities.utils import get_viewname
__all__ = ( __all__ = (
'DynamicModelChoiceField', 'DynamicModelChoiceField',
@ -101,10 +102,8 @@ class DynamicModelChoiceMixin:
# Set the data URL on the APISelect widget (if not already set) # Set the data URL on the APISelect widget (if not already set)
widget = bound_field.field.widget widget = bound_field.field.widget
if not widget.attrs.get('data-url'): if not widget.attrs.get('data-url'):
app_label = self.queryset.model._meta.app_label viewname = get_viewname(self.queryset.model, action='list', rest_api=True)
model_name = self.queryset.model._meta.model_name widget.attrs['data-url'] = reverse(viewname)
data_url = reverse('{}-api:{}-list'.format(app_label, model_name))
widget.attrs['data-url'] = data_url
return bound_field return bound_field

View File

@ -17,19 +17,32 @@ from extras.utils import is_taggable
from utilities.constants import HTTP_REQUEST_META_SAFE_COPY from utilities.constants import HTTP_REQUEST_META_SAFE_COPY
def get_viewname(model, action=None): def get_viewname(model, action=None, rest_api=False):
""" """
Return the view name for the given model and action, if valid. Return the view name for the given model and action, if valid.
:param model: The model or instance to which the view applies :param model: The model or instance to which the view applies
:param action: A string indicating the desired action (if any); e.g. "add" or "list" :param action: A string indicating the desired action (if any); e.g. "add" or "list"
:param rest_api: A boolean indicating whether this is a REST API view
""" """
viewname = f'{model._meta.app_label}:{model._meta.model_name}' is_plugin = isinstance(model._meta.app_config, PluginConfig)
app_label = model._meta.app_label
model_name = model._meta.model_name
# Determine whether this is a plugin view and adjust the namespace appropriately if rest_api:
if isinstance(model._meta.app_config, PluginConfig): if is_plugin:
viewname = f'plugins-api:{app_label}:{model_name}'
else:
viewname = f'{app_label}-api:{model_name}'
# Append the action, if any
if action:
viewname = f'{viewname}-{action}'
else:
viewname = f'{app_label}:{model_name}'
# Prepend the plugins namespace if this is a plugin model
if is_plugin:
viewname = f'plugins:{viewname}' viewname = f'plugins:{viewname}'
# Append the action, if any # Append the action, if any
if action: if action:
viewname = f'{viewname}_{action}' viewname = f'{viewname}_{action}'