From d6443f7b37f8e86fc99f1cd58e8a8ca18cfa3290 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Mon, 13 Aug 2018 12:37:57 -0400 Subject: [PATCH] Standardized "save and add/continue" functions --- netbox/circuits/views.py | 3 +- netbox/dcim/views.py | 3 ++ netbox/extras/views.py | 1 + netbox/ipam/views.py | 1 + netbox/templates/utilities/obj_edit.html | 26 ++++++++---- netbox/utilities/views.py | 51 ++++++++++++++++++++++-- 6 files changed, 74 insertions(+), 11 deletions(-) diff --git a/netbox/circuits/views.py b/netbox/circuits/views.py index e116e4556..f34e5f9cc 100644 --- a/netbox/circuits/views.py +++ b/netbox/circuits/views.py @@ -5,7 +5,7 @@ from django.contrib.auth.decorators import permission_required from django.contrib.auth.mixins import PermissionRequiredMixin from django.db import transaction from django.db.models import Count -from django.shortcuts import get_object_or_404, redirect, render +from django.shortcuts import get_object_or_404, redirect, render, reverse from django.views.generic import View from extras.models import Graph, GRAPH_TYPE_PROVIDER @@ -261,6 +261,7 @@ class CircuitTerminationCreateView(PermissionRequiredMixin, ObjectEditView): model = CircuitTermination model_form = forms.CircuitTerminationForm template_name = 'circuits/circuittermination_edit.html' + enable_add_another = False def alter_obj(self, obj, request, url_args, url_kwargs): if 'circuit' in url_kwargs: diff --git a/netbox/dcim/views.py b/netbox/dcim/views.py index eb7f71a25..1b729c847 100644 --- a/netbox/dcim/views.py +++ b/netbox/dcim/views.py @@ -452,6 +452,9 @@ class RackReservationCreateView(PermissionRequiredMixin, ObjectEditView): def get_return_url(self, request, obj): return obj.rack.get_absolute_url() + def get_add_url(self, obj): + return reverse('dcim:rack_add_reservation', kwargs={'rack': obj.rack.pk}) + class RackReservationEditView(RackReservationCreateView): permission_required = 'dcim.change_rackreservation' diff --git a/netbox/extras/views.py b/netbox/extras/views.py index 90d0d698d..ec8349690 100644 --- a/netbox/extras/views.py +++ b/netbox/extras/views.py @@ -195,6 +195,7 @@ class ImageAttachmentEditView(PermissionRequiredMixin, ObjectEditView): permission_required = 'extras.change_imageattachment' model = ImageAttachment model_form = ImageAttachmentForm + enable_add_another = False def alter_obj(self, imageattachment, request, args, kwargs): if not imageattachment.pk: diff --git a/netbox/ipam/views.py b/netbox/ipam/views.py index 91c741789..605ad6fb4 100644 --- a/netbox/ipam/views.py +++ b/netbox/ipam/views.py @@ -983,6 +983,7 @@ class ServiceCreateView(PermissionRequiredMixin, ObjectEditView): model = Service model_form = forms.ServiceForm template_name = 'ipam/service_edit.html' + enable_add_another = False def alter_obj(self, obj, request, url_args, url_kwargs): if 'device' in url_kwargs: diff --git a/netbox/templates/utilities/obj_edit.html b/netbox/templates/utilities/obj_edit.html index 9ea36985b..712e880b8 100644 --- a/netbox/templates/utilities/obj_edit.html +++ b/netbox/templates/utilities/obj_edit.html @@ -35,13 +35,25 @@
{% block buttons %} - {% if obj.pk %} -

- {% else %} -

-

- {% endif %} -

Cancel

+
+ + + +
+
+ Cancel +
{% endblock %}
diff --git a/netbox/utilities/views.py b/netbox/utilities/views.py index e11d681ef..ff6df5496 100644 --- a/netbox/utilities/views.py +++ b/netbox/utilities/views.py @@ -15,7 +15,7 @@ from django.http import HttpResponseServerError from django.shortcuts import get_object_or_404, redirect, render from django.template import loader from django.template.exceptions import TemplateDoesNotExist, TemplateSyntaxError -from django.urls import reverse +from django.urls import NoReverseMatch, reverse from django.utils.html import escape from django.utils.http import is_safe_url from django.utils.safestring import mark_safe @@ -171,10 +171,14 @@ class ObjectEditView(GetReturnURLMixin, View): model: The model of the object being edited model_form: The form used to create or edit the object template_name: The name of the template + enable_continue_editing: Enable the option to save and continue editing the object + enable_add_another: Enable the option to save the object and create another """ model = None model_form = None template_name = 'utilities/obj_edit.html' + enable_continue_editing = True + enable_add_another = True def get_object(self, kwargs): # Look up object by slug or PK. Return None if neither was provided. @@ -189,6 +193,36 @@ class ObjectEditView(GetReturnURLMixin, View): # given some parameter from the request URL. return obj + def get_edit_url(self, obj): + """ + Return the URL for editing an existing object (used for "save and continue editing" button). + """ + url_name = '{}:{}_edit'.format( + self.model._meta.app_label, + self.model._meta.model_name + ) + if hasattr(obj, 'slug'): + kwargs = {'slug': obj.slug} + else: + kwargs = {'pk': obj.pk} + try: + return reverse(url_name, kwargs=kwargs) + except NoReverseMatch: + return None + + def get_add_url(self, obj): + """ + Return the URL for creating a new object (used for "save and add another" button). + """ + url_name = '{}:{}_add'.format( + self.model._meta.app_label, + self.model._meta.model_name + ) + try: + return reverse(url_name) + except NoReverseMatch: + return None + def get(self, request, *args, **kwargs): obj = self.get_object(kwargs) @@ -201,6 +235,8 @@ class ObjectEditView(GetReturnURLMixin, View): 'obj': obj, 'obj_type': self.model._meta.verbose_name, 'form': form, + 'enable_continue_editing': self.enable_continue_editing, + 'enable_add_another': self.enable_add_another, 'return_url': self.get_return_url(request, obj), }) @@ -224,8 +260,17 @@ class ObjectEditView(GetReturnURLMixin, View): msg = '{} {}'.format(msg, escape(obj)) messages.success(request, mark_safe(msg)) - if '_addanother' in request.POST: - return redirect(request.get_full_path()) + # Continue editing the current object + if '_continue' in request.POST and self.enable_continue_editing: + edit_url = self.get_edit_url(obj) + if edit_url is not None: + return redirect(edit_url) + + # Create another object of the same type + elif '_addanother' in request.POST and self.enable_add_another: + add_url = self.get_add_url(obj) + if add_url is not None: + return redirect(add_url) return_url = form.cleaned_data.get('return_url') if return_url is not None and is_safe_url(url=return_url, host=request.get_host()):