Parcourir la source

Generic view cleanup

jeremystretch il y a 4 ans
Parent
commit
2dad35186a

+ 1 - 1
netbox/circuits/views.py

@@ -320,7 +320,7 @@ class CircuitTerminationEditView(generic.ObjectEditView):
     model_form = forms.CircuitTerminationForm
     model_form = forms.CircuitTerminationForm
     template_name = 'circuits/circuittermination_edit.html'
     template_name = 'circuits/circuittermination_edit.html'
 
 
-    def alter_obj(self, obj, request, url_args, url_kwargs):
+    def alter_object(self, obj, request, url_args, url_kwargs):
         if 'circuit' in url_kwargs:
         if 'circuit' in url_kwargs:
             obj.circuit = get_object_or_404(Circuit, pk=url_kwargs['circuit'])
             obj.circuit = get_object_or_404(Circuit, pk=url_kwargs['circuit'])
         return obj
         return obj

+ 7 - 6
netbox/dcim/views.py

@@ -671,7 +671,7 @@ class RackReservationEditView(generic.ObjectEditView):
     queryset = RackReservation.objects.all()
     queryset = RackReservation.objects.all()
     model_form = forms.RackReservationForm
     model_form = forms.RackReservationForm
 
 
-    def alter_obj(self, obj, request, args, kwargs):
+    def alter_object(self, obj, request, args, kwargs):
         if not obj.pk:
         if not obj.pk:
             if 'rack' in request.GET:
             if 'rack' in request.GET:
                 obj.rack = get_object_or_404(Rack, pk=request.GET.get('rack'))
                 obj.rack = get_object_or_404(Rack, pk=request.GET.get('rack'))
@@ -2342,7 +2342,7 @@ class CableCreateView(generic.ObjectEditView):
 
 
         return super().dispatch(request, *args, **kwargs)
         return super().dispatch(request, *args, **kwargs)
 
 
-    def alter_obj(self, obj, request, url_args, url_kwargs):
+    def alter_object(self, obj, request, url_args, url_kwargs):
         termination_a_type = url_kwargs.get('termination_a_type')
         termination_a_type = url_kwargs.get('termination_a_type')
         termination_a_id = url_kwargs.get('termination_a_id')
         termination_a_id = url_kwargs.get('termination_a_id')
         termination_b_type_name = url_kwargs.get('termination_b_type')
         termination_b_type_name = url_kwargs.get('termination_b_type')
@@ -2355,7 +2355,8 @@ class CableCreateView(generic.ObjectEditView):
         return obj
         return obj
 
 
     def get(self, request, *args, **kwargs):
     def get(self, request, *args, **kwargs):
-        obj = self.alter_obj(self.get_object(kwargs), request, args, kwargs)
+        obj = self.get_object(**kwargs)
+        obj = self.alter_object(obj, request, args, kwargs)
 
 
         # Parse initial data manually to avoid setting field values as lists
         # Parse initial data manually to avoid setting field values as lists
         initial_data = {k: request.GET[k] for k in request.GET}
         initial_data = {k: request.GET[k] for k in request.GET}
@@ -2423,7 +2424,7 @@ class ConsoleConnectionsListView(generic.ObjectListView):
     template_name = 'dcim/connections_list.html'
     template_name = 'dcim/connections_list.html'
     action_buttons = ('export',)
     action_buttons = ('export',)
 
 
-    def extra_context(self):
+    def get_extra_context(self, request):
         return {
         return {
             'title': 'Console Connections'
             'title': 'Console Connections'
         }
         }
@@ -2437,7 +2438,7 @@ class PowerConnectionsListView(generic.ObjectListView):
     template_name = 'dcim/connections_list.html'
     template_name = 'dcim/connections_list.html'
     action_buttons = ('export',)
     action_buttons = ('export',)
 
 
-    def extra_context(self):
+    def get_extra_context(self, request):
         return {
         return {
             'title': 'Power Connections'
             'title': 'Power Connections'
         }
         }
@@ -2451,7 +2452,7 @@ class InterfaceConnectionsListView(generic.ObjectListView):
     template_name = 'dcim/connections_list.html'
     template_name = 'dcim/connections_list.html'
     action_buttons = ('export',)
     action_buttons = ('export',)
 
 
-    def extra_context(self):
+    def get_extra_context(self, request):
         return {
         return {
             'title': 'Interface Connections'
             'title': 'Interface Connections'
         }
         }

+ 2 - 2
netbox/extras/views.py

@@ -472,7 +472,7 @@ class ImageAttachmentEditView(generic.ObjectEditView):
     queryset = ImageAttachment.objects.all()
     queryset = ImageAttachment.objects.all()
     model_form = forms.ImageAttachmentForm
     model_form = forms.ImageAttachmentForm
 
 
-    def alter_obj(self, instance, request, args, kwargs):
+    def alter_object(self, instance, request, args, kwargs):
         if not instance.pk:
         if not instance.pk:
             # Assign the parent object based on URL kwargs
             # Assign the parent object based on URL kwargs
             content_type = get_object_or_404(ContentType, pk=request.GET.get('content_type'))
             content_type = get_object_or_404(ContentType, pk=request.GET.get('content_type'))
@@ -510,7 +510,7 @@ class JournalEntryEditView(generic.ObjectEditView):
     queryset = JournalEntry.objects.all()
     queryset = JournalEntry.objects.all()
     model_form = forms.JournalEntryForm
     model_form = forms.JournalEntryForm
 
 
-    def alter_obj(self, obj, request, args, kwargs):
+    def alter_object(self, obj, request, args, kwargs):
         if not obj.pk:
         if not obj.pk:
             obj.created_by = request.user
             obj.created_by = request.user
         return obj
         return obj

+ 3 - 3
netbox/ipam/views.py

@@ -721,7 +721,7 @@ class IPAddressEditView(generic.ObjectEditView):
     model_form = forms.IPAddressForm
     model_form = forms.IPAddressForm
     template_name = 'ipam/ipaddress_edit.html'
     template_name = 'ipam/ipaddress_edit.html'
 
 
-    def alter_obj(self, obj, request, url_args, url_kwargs):
+    def alter_object(self, obj, request, url_args, url_kwargs):
 
 
         if 'interface' in request.GET:
         if 'interface' in request.GET:
             try:
             try:
@@ -975,7 +975,7 @@ class FHRPGroupAssignmentEditView(generic.ObjectEditView):
     model_form = forms.FHRPGroupAssignmentForm
     model_form = forms.FHRPGroupAssignmentForm
     template_name = 'ipam/fhrpgroupassignment_edit.html'
     template_name = 'ipam/fhrpgroupassignment_edit.html'
 
 
-    def alter_obj(self, instance, request, args, kwargs):
+    def alter_object(self, instance, request, args, kwargs):
         if not instance.pk:
         if not instance.pk:
             # Assign the interface based on URL kwargs
             # Assign the interface based on URL kwargs
             content_type = get_object_or_404(ContentType, pk=request.GET.get('interface_type'))
             content_type = get_object_or_404(ContentType, pk=request.GET.get('interface_type'))
@@ -1092,7 +1092,7 @@ class ServiceEditView(generic.ObjectEditView):
     model_form = forms.ServiceForm
     model_form = forms.ServiceForm
     template_name = 'ipam/service_edit.html'
     template_name = 'ipam/service_edit.html'
 
 
-    def alter_obj(self, obj, request, url_args, url_kwargs):
+    def alter_object(self, obj, request, url_args, url_kwargs):
         if 'device' in url_kwargs:
         if 'device' in url_kwargs:
             obj.device = get_object_or_404(
             obj.device = get_object_or_404(
                 Device.objects.restrict(request.user),
                 Device.objects.restrict(request.user),

+ 88 - 38
netbox/netbox/views/generic.py

@@ -55,14 +55,16 @@ class ObjectView(ObjectPermissionRequiredMixin, View):
         """
         """
         Return any additional context data for the template.
         Return any additional context data for the template.
 
 
-        request: The current request
-        instance: The object being viewed
+        :param request: The current request
+        :param instance: The object being viewed
         """
         """
         return {}
         return {}
 
 
     def get(self, request, *args, **kwargs):
     def get(self, request, *args, **kwargs):
         """
         """
-        Generic GET handler for accessing an object by PK or slug
+        GET request handler. *args and **kwargs are passed to identify the object being queried.
+
+        :param request: The current request
         """
         """
         instance = get_object_or_404(self.queryset, **kwargs)
         instance = get_object_or_404(self.queryset, **kwargs)
 
 
@@ -78,10 +80,11 @@ class ObjectListView(ObjectPermissionRequiredMixin, View):
 
 
     queryset: The queryset of objects to display. Note: Prefetching related objects is not necessary, as the
     queryset: The queryset of objects to display. Note: Prefetching related objects is not necessary, as the
       table will prefetch objects as needed depending on the columns being displayed.
       table will prefetch objects as needed depending on the columns being displayed.
-    filter: A django-filter FilterSet that is applied to the queryset
-    filter_form: The form used to render filter options
+    filterset: A django-filter FilterSet that is applied to the queryset
+    filterset_form: The form used to render filter options
     table: The django-tables2 Table used to render the objects list
     table: The django-tables2 Table used to render the objects list
     template_name: The name of the template
     template_name: The name of the template
+    action_buttons: A list of buttons to include at the top of the page
     """
     """
     queryset = None
     queryset = None
     filterset = None
     filterset = None
@@ -94,6 +97,13 @@ class ObjectListView(ObjectPermissionRequiredMixin, View):
         return get_permission_for_model(self.queryset.model, 'view')
         return get_permission_for_model(self.queryset.model, 'view')
 
 
     def get_table(self, request, permissions):
     def get_table(self, request, permissions):
+        """
+        Return the django-tables2 Table instance to be used for rendering the objects list.
+
+        :param request: The current request
+        :param permissions: A dictionary mapping of the view, add, change, and delete permissions to booleans indicating
+            whether the user has each
+        """
         table = self.table(self.queryset, user=request.user)
         table = self.table(self.queryset, user=request.user)
         if 'pk' in table.base_columns and (permissions['change'] or permissions['delete']):
         if 'pk' in table.base_columns and (permissions['change'] or permissions['delete']):
             table.columns.show('pk')
             table.columns.show('pk')
@@ -143,7 +153,20 @@ class ObjectListView(ObjectPermissionRequiredMixin, View):
             messages.error(request, f"There was an error rendering the selected export template ({template.name}): {e}")
             messages.error(request, f"There was an error rendering the selected export template ({template.name}): {e}")
             return redirect(request.path)
             return redirect(request.path)
 
 
+    def get_extra_context(self, request):
+        """
+        Return any additional context data for the template.
+
+        :param request: The current request
+        """
+        return {}
+
     def get(self, request):
     def get(self, request):
+        """
+        GET request handler.
+
+        :param request: The current request
+        """
         model = self.queryset.model
         model = self.queryset.model
         content_type = ContentType.objects.get_for_model(model)
         content_type = ContentType.objects.get_for_model(model)
 
 
@@ -192,19 +215,16 @@ class ObjectListView(ObjectPermissionRequiredMixin, View):
             'action_buttons': self.action_buttons,
             'action_buttons': self.action_buttons,
             'filter_form': self.filterset_form(request.GET, label_suffix='') if self.filterset_form else None,
             'filter_form': self.filterset_form(request.GET, label_suffix='') if self.filterset_form else None,
         }
         }
-        context.update(self.extra_context())
+        context.update(self.get_extra_context(request))
 
 
         return render(request, self.template_name, context)
         return render(request, self.template_name, context)
 
 
-    def extra_context(self):
-        return {}
-
 
 
 class ObjectEditView(GetReturnURLMixin, ObjectPermissionRequiredMixin, View):
 class ObjectEditView(GetReturnURLMixin, ObjectPermissionRequiredMixin, View):
     """
     """
     Create or edit a single object.
     Create or edit a single object.
 
 
-    queryset: The base queryset for the object being modified
+    queryset: The base QuerySet for the object being modified
     model_form: The form used to create or edit the object
     model_form: The form used to create or edit the object
     template_name: The name of the template
     template_name: The name of the template
     """
     """
@@ -217,25 +237,31 @@ class ObjectEditView(GetReturnURLMixin, ObjectPermissionRequiredMixin, View):
         # we are modifying an existing object or creating a new one.
         # we are modifying an existing object or creating a new one.
         return get_permission_for_model(self.queryset.model, self._permission_action)
         return get_permission_for_model(self.queryset.model, self._permission_action)
 
 
-    def get_object(self, kwargs):
-        # Look up an existing object by slug or PK, if provided.
-        if 'slug' in kwargs:
-            obj = get_object_or_404(self.queryset, slug=kwargs['slug'])
-        elif 'pk' in kwargs:
-            obj = get_object_or_404(self.queryset, pk=kwargs['pk'])
-        # Otherwise, return a new instance.
-        else:
-            return self.queryset.model()
+    def get_object(self, **kwargs):
+        """
+        Return an instance for editing. If a PK has been specified, this will be an existing object.
 
 
-        # Take a snapshot of change-logged models
-        if hasattr(obj, 'snapshot'):
-            obj.snapshot()
+        :param kwargs: URL path kwargs
+        """
+        if 'pk' in kwargs:
+            obj = get_object_or_404(self.queryset, **kwargs)
+            # Take a snapshot of change-logged models
+            if hasattr(obj, 'snapshot'):
+                obj.snapshot()
+            return obj
 
 
-        return obj
+        return self.queryset.model()
 
 
-    def alter_obj(self, obj, request, url_args, url_kwargs):
-        # Allow views to add extra info to an object before it is processed. For example, a parent object can be defined
-        # given some parameter from the request URL.
+    def alter_object(self, obj, request, url_args, url_kwargs):
+        """
+        Provides a hook for views to modify an object before it is processed. For example, a parent object can be
+        defined given some parameter from the request URL.
+
+        :param obj: The object being edited
+        :param request: The current request
+        :param url_args: URL path args
+        :param url_kwargs: URL path kwargs
+        """
         return obj
         return obj
 
 
     def dispatch(self, request, *args, **kwargs):
     def dispatch(self, request, *args, **kwargs):
@@ -245,7 +271,13 @@ class ObjectEditView(GetReturnURLMixin, ObjectPermissionRequiredMixin, View):
         return super().dispatch(request, *args, **kwargs)
         return super().dispatch(request, *args, **kwargs)
 
 
     def get(self, request, *args, **kwargs):
     def get(self, request, *args, **kwargs):
-        obj = self.alter_obj(self.get_object(kwargs), request, args, kwargs)
+        """
+        GET request handler.
+
+        :param request: The current request
+        """
+        obj = self.get_object(**kwargs)
+        obj = self.alter_object(obj, request, args, kwargs)
 
 
         initial_data = normalize_querydict(request.GET)
         initial_data = normalize_querydict(request.GET)
         form = self.model_form(instance=obj, initial=initial_data)
         form = self.model_form(instance=obj, initial=initial_data)
@@ -259,8 +291,15 @@ class ObjectEditView(GetReturnURLMixin, ObjectPermissionRequiredMixin, View):
         })
         })
 
 
     def post(self, request, *args, **kwargs):
     def post(self, request, *args, **kwargs):
+        """
+        POST request handler.
+
+        :param request: The current request
+        """
         logger = logging.getLogger('netbox.views.ObjectEditView')
         logger = logging.getLogger('netbox.views.ObjectEditView')
-        obj = self.alter_obj(self.get_object(kwargs), request, args, kwargs)
+        obj = self.get_object(**kwargs)
+        obj = self.alter_object(obj, request, args, kwargs)
+
         form = self.model_form(
         form = self.model_form(
             data=request.POST,
             data=request.POST,
             files=request.FILES,
             files=request.FILES,
@@ -334,12 +373,13 @@ class ObjectDeleteView(GetReturnURLMixin, ObjectPermissionRequiredMixin, View):
     def get_required_permission(self):
     def get_required_permission(self):
         return get_permission_for_model(self.queryset.model, 'delete')
         return get_permission_for_model(self.queryset.model, 'delete')
 
 
-    def get_object(self, kwargs):
-        # Look up object by slug if one has been provided. Otherwise, use PK.
-        if 'slug' in kwargs:
-            obj = get_object_or_404(self.queryset, slug=kwargs['slug'])
-        else:
-            obj = get_object_or_404(self.queryset, pk=kwargs['pk'])
+    def get_object(self, **kwargs):
+        """
+        Return an instance for deletion. If a PK has been specified, this will be an existing object.
+
+        :param kwargs: URL path kwargs
+        """
+        obj = get_object_or_404(self.queryset, **kwargs)
 
 
         # Take a snapshot of change-logged models
         # Take a snapshot of change-logged models
         if hasattr(obj, 'snapshot'):
         if hasattr(obj, 'snapshot'):
@@ -347,8 +387,13 @@ class ObjectDeleteView(GetReturnURLMixin, ObjectPermissionRequiredMixin, View):
 
 
         return obj
         return obj
 
 
-    def get(self, request, **kwargs):
-        obj = self.get_object(kwargs)
+    def get(self, request, *args, **kwargs):
+        """
+        GET request handler.
+
+        :param request: The current request
+        """
+        obj = self.get_object(**kwargs)
         form = ConfirmationForm(initial=request.GET)
         form = ConfirmationForm(initial=request.GET)
 
 
         return render(request, self.template_name, {
         return render(request, self.template_name, {
@@ -358,9 +403,14 @@ class ObjectDeleteView(GetReturnURLMixin, ObjectPermissionRequiredMixin, View):
             'return_url': self.get_return_url(request, obj),
             'return_url': self.get_return_url(request, obj),
         })
         })
 
 
-    def post(self, request, **kwargs):
+    def post(self, request, *args, **kwargs):
+        """
+        POST request handler.
+
+        :param request: The current request
+        """
         logger = logging.getLogger('netbox.views.ObjectDeleteView')
         logger = logging.getLogger('netbox.views.ObjectDeleteView')
-        obj = self.get_object(kwargs)
+        obj = self.get_object(**kwargs)
         form = ConfirmationForm(request.POST)
         form = ConfirmationForm(request.POST)
 
 
         if form.is_valid():
         if form.is_valid():

+ 1 - 1
netbox/tenancy/views.py

@@ -353,7 +353,7 @@ class ContactAssignmentEditView(generic.ObjectEditView):
     model_form = forms.ContactAssignmentForm
     model_form = forms.ContactAssignmentForm
     template_name = 'tenancy/contactassignment_edit.html'
     template_name = 'tenancy/contactassignment_edit.html'
 
 
-    def alter_obj(self, instance, request, args, kwargs):
+    def alter_object(self, instance, request, args, kwargs):
         if not instance.pk:
         if not instance.pk:
             # Assign the object based on URL kwargs
             # Assign the object based on URL kwargs
             content_type = get_object_or_404(ContentType, pk=request.GET.get('content_type'))
             content_type = get_object_or_404(ContentType, pk=request.GET.get('content_type'))