diff --git a/netbox/dcim/forms/model_forms.py b/netbox/dcim/forms/model_forms.py index 1c72a12dd..c1a8355db 100644 --- a/netbox/dcim/forms/model_forms.py +++ b/netbox/dcim/forms/model_forms.py @@ -14,7 +14,7 @@ from tenancy.forms import TenancyForm from utilities.forms import ( APISelect, add_blank_choice, BootstrapMixin, ClearableFileInput, CommentField, ContentTypeChoiceField, DynamicModelChoiceField, DynamicModelMultipleChoiceField, JSONField, NumericArrayField, SelectWithPK, - SlugField, SelectSpeedWidget, + SlugField, SelectSpeedWidget, APISelectWithSelector ) from virtualization.models import Cluster, ClusterGroup from wireless.models import WirelessLAN, WirelessLANGroup @@ -441,26 +441,27 @@ class PlatformForm(NetBoxModelForm): class DeviceForm(TenancyForm, NetBoxModelForm): - region = DynamicModelChoiceField( - queryset=Region.objects.all(), - required=False, - initial_params={ - 'sites': '$site' - } - ) - site_group = DynamicModelChoiceField( - queryset=SiteGroup.objects.all(), - required=False, - initial_params={ - 'sites': '$site' - } - ) + # region = DynamicModelChoiceField( + # queryset=Region.objects.all(), + # required=False, + # initial_params={ + # 'sites': '$site' + # } + # ) + # site_group = DynamicModelChoiceField( + # queryset=SiteGroup.objects.all(), + # required=False, + # initial_params={ + # 'sites': '$site' + # } + # ) site = DynamicModelChoiceField( queryset=Site.objects.all(), query_params={ 'region_id': '$region', 'group_id': '$site_group', - } + }, + widget=APISelectWithSelector ) location = DynamicModelChoiceField( queryset=Location.objects.all(), @@ -556,7 +557,7 @@ class DeviceForm(TenancyForm, NetBoxModelForm): class Meta: model = Device fields = [ - 'name', 'device_role', 'device_type', 'serial', 'asset_tag', 'region', 'site_group', 'site', 'rack', + 'name', 'device_role', 'device_type', 'serial', 'asset_tag', 'site', 'rack', 'location', 'position', 'face', 'status', 'airflow', 'platform', 'primary_ip4', 'primary_ip6', 'cluster_group', 'cluster', 'tenant_group', 'tenant', 'virtual_chassis', 'vc_position', 'vc_priority', 'description', 'config_template', 'comments', 'tags', 'local_context_data' diff --git a/netbox/netbox/urls.py b/netbox/netbox/urls.py index 22c47f7bb..8c859528c 100644 --- a/netbox/netbox/urls.py +++ b/netbox/netbox/urls.py @@ -10,7 +10,7 @@ from extras.plugins.urls import plugin_admin_patterns, plugin_patterns, plugin_a from netbox.api.views import APIRootView, StatusView from netbox.graphql.schema import schema from netbox.graphql.views import GraphQLView -from netbox.views import HomeView, StaticMediaFailureView, SearchView +from netbox.views import HomeView, StaticMediaFailureView, SearchView, htmx from users.views import LoginView, LogoutView from .admin import admin_site @@ -51,6 +51,9 @@ _patterns = [ path('virtualization/', include('virtualization.urls')), path('wireless/', include('wireless.urls')), + # HTMX views + path('htmx/object-selector/', htmx.ObjectSelectorView.as_view(), name='htmx_object_selector'), + # API path('api/', APIRootView.as_view(), name='api-root'), path('api/circuits/', include('circuits.api.urls')), diff --git a/netbox/netbox/views/htmx.py b/netbox/netbox/views/htmx.py new file mode 100644 index 000000000..bde710fe3 --- /dev/null +++ b/netbox/netbox/views/htmx.py @@ -0,0 +1,20 @@ +from django.shortcuts import render +from django.views.generic import View + +from dcim.forms import SiteFilterForm + + +class ObjectSelectorView(View): + template_name = 'htmx/object_selector.html' + + def get(self, request): + form_class = self._get_form_class() + form = form_class(request.GET) + + return render(request, self.template_name, { + 'form': form, + }) + + def _get_form_class(self): + # TODO: Determine form class from request parameters + return SiteFilterForm diff --git a/netbox/templates/dcim/device_edit.html b/netbox/templates/dcim/device_edit.html index 07e3bbdc9..15725f559 100644 --- a/netbox/templates/dcim/device_edit.html +++ b/netbox/templates/dcim/device_edit.html @@ -29,8 +29,8 @@