Coverage for netbox/views/htmx.py: 28%
39 statements
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-10 18:35 +0000
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-10 18:35 +0000
1from django.contrib.auth.mixins import LoginRequiredMixin
2from django.contrib.contenttypes.models import ContentType
3from django.core.exceptions import ObjectDoesNotExist
4from django.http import Http404
5from django.shortcuts import render
6from django.utils.module_loading import import_string
7from django.views.generic import View
10class ObjectSelectorView(LoginRequiredMixin, View):
11 template_name = 'htmx/object_selector.html'
13 def get(self, request):
14 model = self._get_model(request.GET.get('_model', ''))
16 form_class = self._get_form_class(model)
17 form = form_class(request.GET)
19 if '_search' in request.GET:
20 # Return only search results
21 filterset = self._get_filterset_class(model)
23 queryset = model.objects.restrict(request.user)
24 if filterset:
25 queryset = filterset(request.GET, queryset, request=request).qs
27 return render(request, 'htmx/object_selector_results.html', {
28 'results': queryset[:100],
29 })
31 return render(request, self.template_name, {
32 'form': form,
33 'model': model,
34 'target_id': request.GET.get('target'),
35 })
37 def _get_model(self, label):
38 try:
39 app_label, model_name = label.split('.')
40 content_type = ContentType.objects.get_by_natural_key(app_label, model_name)
41 except (ValueError, ObjectDoesNotExist):
42 raise Http404
43 return content_type.model_class()
45 def _get_form_class(self, model):
46 if hasattr(self, 'form_class'):
47 return self.form_class
48 app_label = model._meta.app_label
49 class_name = f'{model.__name__}FilterForm'
50 return import_string(f'{app_label}.forms.{class_name}')
52 def _get_filterset_class(self, model):
53 if hasattr(self, 'filterset_class'):
54 return self.filterset_class
55 app_label = model._meta.app_label
56 class_name = f'{model.__name__}FilterSet'
57 return import_string(f'{app_label}.filtersets.{class_name}')