Răsfoiți Sursa

Collapsed add/edit functionality into ObjectEditView

Jeremy Stretch 9 ani în urmă
părinte
comite
9df86d5268

+ 3 - 3
netbox/circuits/urls.py

@@ -6,7 +6,7 @@ urlpatterns = [
 
 
     # Providers
     # Providers
     url(r'^providers/$', views.ProviderListView.as_view(), name='provider_list'),
     url(r'^providers/$', views.ProviderListView.as_view(), name='provider_list'),
-    url(r'^providers/add/$', views.ProviderAddView.as_view(), name='provider_add'),
+    url(r'^providers/add/$', views.ProviderEditView.as_view(), name='provider_add'),
     url(r'^providers/import/$', views.ProviderBulkImportView.as_view(), name='provider_import'),
     url(r'^providers/import/$', views.ProviderBulkImportView.as_view(), name='provider_import'),
     url(r'^providers/edit/$', views.ProviderBulkEditView.as_view(), name='provider_bulk_edit'),
     url(r'^providers/edit/$', views.ProviderBulkEditView.as_view(), name='provider_bulk_edit'),
     url(r'^providers/delete/$', views.ProviderBulkDeleteView.as_view(), name='provider_bulk_delete'),
     url(r'^providers/delete/$', views.ProviderBulkDeleteView.as_view(), name='provider_bulk_delete'),
@@ -16,13 +16,13 @@ urlpatterns = [
 
 
     # Circuit types
     # Circuit types
     url(r'^circuit-types/$', views.CircuitTypeListView.as_view(), name='circuittype_list'),
     url(r'^circuit-types/$', views.CircuitTypeListView.as_view(), name='circuittype_list'),
-    url(r'^circuit-types/add/$', views.CircuitTypeAddView.as_view(), name='circuittype_add'),
+    url(r'^circuit-types/add/$', views.CircuitTypeEditView.as_view(), name='circuittype_add'),
     url(r'^circuit-types/delete/$', views.CircuitTypeBulkDeleteView.as_view(), name='circuittype_bulk_delete'),
     url(r'^circuit-types/delete/$', views.CircuitTypeBulkDeleteView.as_view(), name='circuittype_bulk_delete'),
     url(r'^circuit-types/(?P<slug>[\w-]+)/edit/$', views.CircuitTypeEditView.as_view(), name='circuittype_edit'),
     url(r'^circuit-types/(?P<slug>[\w-]+)/edit/$', views.CircuitTypeEditView.as_view(), name='circuittype_edit'),
 
 
     # Circuits
     # Circuits
     url(r'^circuits/$', views.CircuitListView.as_view(), name='circuit_list'),
     url(r'^circuits/$', views.CircuitListView.as_view(), name='circuit_list'),
-    url(r'^circuits/add/$', views.CircuitAddView.as_view(), name='circuit_add'),
+    url(r'^circuits/add/$', views.CircuitEditView.as_view(), name='circuit_add'),
     url(r'^circuits/import/$', views.CircuitBulkImportView.as_view(), name='circuit_import'),
     url(r'^circuits/import/$', views.CircuitBulkImportView.as_view(), name='circuit_import'),
     url(r'^circuits/edit/$', views.CircuitBulkEditView.as_view(), name='circuit_bulk_edit'),
     url(r'^circuits/edit/$', views.CircuitBulkEditView.as_view(), name='circuit_bulk_edit'),
     url(r'^circuits/delete/$', views.CircuitBulkDeleteView.as_view(), name='circuit_bulk_delete'),
     url(r'^circuits/delete/$', views.CircuitBulkDeleteView.as_view(), name='circuit_bulk_delete'),

+ 7 - 27
netbox/circuits/views.py

@@ -3,8 +3,8 @@ from django.contrib.auth.mixins import PermissionRequiredMixin
 from django.db.models import Count
 from django.db.models import Count
 from django.shortcuts import get_object_or_404, render
 from django.shortcuts import get_object_or_404, render
 
 
-from utilities.views import BulkImportView, BulkEditView, BulkDeleteView, ObjectListView, ObjectAddView,\
-    ObjectEditView, ObjectDeleteView
+from utilities.views import BulkImportView, BulkEditView, BulkDeleteView, ObjectListView, ObjectEditView,\
+    ObjectDeleteView
 
 
 from .filters import CircuitFilter
 from .filters import CircuitFilter
 from .forms import CircuitTypeForm, CircuitTypeBulkDeleteForm, CircuitForm, CircuitImportForm, CircuitBulkEditForm,\
 from .forms import CircuitTypeForm, CircuitTypeBulkDeleteForm, CircuitForm, CircuitImportForm, CircuitBulkEditForm,\
@@ -36,19 +36,12 @@ def provider(request, slug):
     })
     })
 
 
 
 
-class ProviderAddView(PermissionRequiredMixin, ObjectAddView):
-    permission_required = 'circuits.add_provider'
-    model = Provider
-    form_class = ProviderForm
-    template_name = 'circuits/provider_edit.html'
-    cancel_url = 'circuits:provider_list'
-
-
 class ProviderEditView(PermissionRequiredMixin, ObjectEditView):
 class ProviderEditView(PermissionRequiredMixin, ObjectEditView):
     permission_required = 'circuits.change_provider'
     permission_required = 'circuits.change_provider'
     model = Provider
     model = Provider
     form_class = ProviderForm
     form_class = ProviderForm
     template_name = 'circuits/provider_edit.html'
     template_name = 'circuits/provider_edit.html'
+    cancel_url = 'circuits:provider_list'
 
 
 
 
 class ProviderDeleteView(PermissionRequiredMixin, ObjectDeleteView):
 class ProviderDeleteView(PermissionRequiredMixin, ObjectDeleteView):
@@ -101,18 +94,12 @@ class CircuitTypeListView(ObjectListView):
     template_name = 'circuits/circuittype_list.html'
     template_name = 'circuits/circuittype_list.html'
 
 
 
 
-class CircuitTypeAddView(PermissionRequiredMixin, ObjectAddView):
-    permission_required = 'circuits.add_circuittype'
-    model = CircuitType
-    form_class = CircuitTypeForm
-    cancel_url = 'circuits:circuittype_list'
-
-
 class CircuitTypeEditView(PermissionRequiredMixin, ObjectEditView):
 class CircuitTypeEditView(PermissionRequiredMixin, ObjectEditView):
     permission_required = 'circuits.change_circuittype'
     permission_required = 'circuits.change_circuittype'
     model = CircuitType
     model = CircuitType
     form_class = CircuitTypeForm
     form_class = CircuitTypeForm
-    return_url = 'circuits:circuittype_list'
+    success_url = 'circuits:circuittype_list'
+    cancel_url = 'circuits:circuittype_list'
 
 
 
 
 class CircuitTypeBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
 class CircuitTypeBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
@@ -144,20 +131,13 @@ def circuit(request, pk):
     })
     })
 
 
 
 
-class CircuitAddView(PermissionRequiredMixin, ObjectAddView):
-    permission_required = 'circuits.add_circuit'
-    model = Circuit
-    form_class = CircuitForm
-    template_name = 'circuits/circuit_edit.html'
-    cancel_url = 'circuits:circuit_list'
-    fields_initial = ['site']
-
-
 class CircuitEditView(PermissionRequiredMixin, ObjectEditView):
 class CircuitEditView(PermissionRequiredMixin, ObjectEditView):
     permission_required = 'circuits.change_circuit'
     permission_required = 'circuits.change_circuit'
     model = Circuit
     model = Circuit
     form_class = CircuitForm
     form_class = CircuitForm
+    fields_initial = ['site']
     template_name = 'circuits/circuit_edit.html'
     template_name = 'circuits/circuit_edit.html'
+    cancel_url = 'circuits:circuit_list'
 
 
 
 
 class CircuitDeleteView(PermissionRequiredMixin, ObjectDeleteView):
 class CircuitDeleteView(PermissionRequiredMixin, ObjectDeleteView):

+ 7 - 7
netbox/dcim/urls.py

@@ -11,7 +11,7 @@ urlpatterns = [
 
 
     # Sites
     # Sites
     url(r'^sites/$', views.SiteListView.as_view(), name='site_list'),
     url(r'^sites/$', views.SiteListView.as_view(), name='site_list'),
-    url(r'^sites/add/$', views.SiteAddView.as_view(), name='site_add'),
+    url(r'^sites/add/$', views.SiteEditView.as_view(), name='site_add'),
     url(r'^sites/import/$', views.SiteBulkImportView.as_view(), name='site_import'),
     url(r'^sites/import/$', views.SiteBulkImportView.as_view(), name='site_import'),
     url(r'^sites/(?P<slug>[\w-]+)/$', views.site, name='site'),
     url(r'^sites/(?P<slug>[\w-]+)/$', views.site, name='site'),
     url(r'^sites/(?P<slug>[\w-]+)/edit/$', views.SiteEditView.as_view(), name='site_edit'),
     url(r'^sites/(?P<slug>[\w-]+)/edit/$', views.SiteEditView.as_view(), name='site_edit'),
@@ -19,13 +19,13 @@ urlpatterns = [
 
 
     # Rack groups
     # Rack groups
     url(r'^rack-groups/$', views.RackGroupListView.as_view(), name='rackgroup_list'),
     url(r'^rack-groups/$', views.RackGroupListView.as_view(), name='rackgroup_list'),
-    url(r'^rack-groups/add/$', views.RackGroupAddView.as_view(), name='rackgroup_add'),
+    url(r'^rack-groups/add/$', views.RackGroupEditView.as_view(), name='rackgroup_add'),
     url(r'^rack-groups/delete/$', views.RackGroupBulkDeleteView.as_view(), name='rackgroup_bulk_delete'),
     url(r'^rack-groups/delete/$', views.RackGroupBulkDeleteView.as_view(), name='rackgroup_bulk_delete'),
     url(r'^rack-groups/(?P<pk>\d+)/edit/$', views.RackGroupEditView.as_view(), name='rackgroup_edit'),
     url(r'^rack-groups/(?P<pk>\d+)/edit/$', views.RackGroupEditView.as_view(), name='rackgroup_edit'),
 
 
     # Racks
     # Racks
     url(r'^racks/$', views.RackListView.as_view(), name='rack_list'),
     url(r'^racks/$', views.RackListView.as_view(), name='rack_list'),
-    url(r'^racks/add/$', views.RackAddView.as_view(), name='rack_add'),
+    url(r'^racks/add/$', views.RackEditView.as_view(), name='rack_add'),
     url(r'^racks/import/$', views.RackBulkImportView.as_view(), name='rack_import'),
     url(r'^racks/import/$', views.RackBulkImportView.as_view(), name='rack_import'),
     url(r'^racks/edit/$', views.RackBulkEditView.as_view(), name='rack_bulk_edit'),
     url(r'^racks/edit/$', views.RackBulkEditView.as_view(), name='rack_bulk_edit'),
     url(r'^racks/delete/$', views.RackBulkDeleteView.as_view(), name='rack_bulk_delete'),
     url(r'^racks/delete/$', views.RackBulkDeleteView.as_view(), name='rack_bulk_delete'),
@@ -35,13 +35,13 @@ urlpatterns = [
 
 
     # Manufacturers
     # Manufacturers
     url(r'^manufacturers/$', views.ManufacturerListView.as_view(), name='manufacturer_list'),
     url(r'^manufacturers/$', views.ManufacturerListView.as_view(), name='manufacturer_list'),
-    url(r'^manufacturers/add/$', views.ManufacturerAddView.as_view(), name='manufacturer_add'),
+    url(r'^manufacturers/add/$', views.ManufacturerEditView.as_view(), name='manufacturer_add'),
     url(r'^manufacturers/delete/$', views.ManufacturerBulkDeleteView.as_view(), name='manufacturer_bulk_delete'),
     url(r'^manufacturers/delete/$', views.ManufacturerBulkDeleteView.as_view(), name='manufacturer_bulk_delete'),
     url(r'^manufacturers/(?P<slug>[\w-]+)/edit/$', views.ManufacturerEditView.as_view(), name='manufacturer_edit'),
     url(r'^manufacturers/(?P<slug>[\w-]+)/edit/$', views.ManufacturerEditView.as_view(), name='manufacturer_edit'),
 
 
     # Device types
     # Device types
     url(r'^device-types/$', views.DeviceTypeListView.as_view(), name='devicetype_list'),
     url(r'^device-types/$', views.DeviceTypeListView.as_view(), name='devicetype_list'),
-    url(r'^device-types/add/$', views.DeviceTypeAddView.as_view(), name='devicetype_add'),
+    url(r'^device-types/add/$', views.DeviceTypeEditView.as_view(), name='devicetype_add'),
     url(r'^device-types/edit/$', views.DeviceTypeBulkEditView.as_view(), name='devicetype_bulk_edit'),
     url(r'^device-types/edit/$', views.DeviceTypeBulkEditView.as_view(), name='devicetype_bulk_edit'),
     url(r'^device-types/delete/$', views.DeviceTypeBulkDeleteView.as_view(), name='devicetype_bulk_delete'),
     url(r'^device-types/delete/$', views.DeviceTypeBulkDeleteView.as_view(), name='devicetype_bulk_delete'),
     url(r'^device-types/(?P<pk>\d+)/$', views.devicetype, name='devicetype'),
     url(r'^device-types/(?P<pk>\d+)/$', views.devicetype, name='devicetype'),
@@ -72,13 +72,13 @@ urlpatterns = [
 
 
     # Device roles
     # Device roles
     url(r'^device-roles/$', views.DeviceRoleListView.as_view(), name='devicerole_list'),
     url(r'^device-roles/$', views.DeviceRoleListView.as_view(), name='devicerole_list'),
-    url(r'^device-roles/add/$', views.DeviceRoleAddView.as_view(), name='devicerole_add'),
+    url(r'^device-roles/add/$', views.DeviceRoleEditView.as_view(), name='devicerole_add'),
     url(r'^device-roles/delete/$', views.DeviceRoleBulkDeleteView.as_view(), name='devicerole_bulk_delete'),
     url(r'^device-roles/delete/$', views.DeviceRoleBulkDeleteView.as_view(), name='devicerole_bulk_delete'),
     url(r'^device-roles/(?P<slug>[\w-]+)/edit/$', views.DeviceRoleEditView.as_view(), name='devicerole_edit'),
     url(r'^device-roles/(?P<slug>[\w-]+)/edit/$', views.DeviceRoleEditView.as_view(), name='devicerole_edit'),
 
 
     # Devices
     # Devices
     url(r'^devices/$', views.DeviceListView.as_view(), name='device_list'),
     url(r'^devices/$', views.DeviceListView.as_view(), name='device_list'),
-    url(r'^devices/add/$', views.DeviceAddView.as_view(), name='device_add'),
+    url(r'^devices/add/$', views.DeviceEditView.as_view(), name='device_add'),
     url(r'^devices/import/$', views.DeviceBulkImportView.as_view(), name='device_import'),
     url(r'^devices/import/$', views.DeviceBulkImportView.as_view(), name='device_import'),
     url(r'^devices/edit/$', views.DeviceBulkEditView.as_view(), name='device_bulk_edit'),
     url(r'^devices/edit/$', views.DeviceBulkEditView.as_view(), name='device_bulk_edit'),
     url(r'^devices/delete/$', views.DeviceBulkDeleteView.as_view(), name='device_bulk_delete'),
     url(r'^devices/delete/$', views.DeviceBulkDeleteView.as_view(), name='device_bulk_delete'),

+ 11 - 58
netbox/dcim/views.py

@@ -17,8 +17,8 @@ from circuits.models import Circuit
 from extras.models import TopologyMap
 from extras.models import TopologyMap
 from utilities.error_handlers import handle_protectederror
 from utilities.error_handlers import handle_protectederror
 from utilities.forms import ConfirmationForm
 from utilities.forms import ConfirmationForm
-from utilities.views import ObjectListView, BulkImportView, BulkEditView, BulkDeleteView, ObjectAddView,\
-    ObjectEditView, ObjectDeleteView
+from utilities.views import ObjectListView, BulkImportView, BulkEditView, BulkDeleteView, ObjectEditView,\
+    ObjectDeleteView
 
 
 from .filters import RackGroupFilter, RackFilter, DeviceTypeFilter, DeviceFilter, ConsoleConnectionFilter,\
 from .filters import RackGroupFilter, RackFilter, DeviceTypeFilter, DeviceFilter, ConsoleConnectionFilter,\
     PowerConnectionFilter, InterfaceConnectionFilter
     PowerConnectionFilter, InterfaceConnectionFilter
@@ -97,19 +97,12 @@ def site(request, slug):
     })
     })
 
 
 
 
-class SiteAddView(PermissionRequiredMixin, ObjectAddView):
-    permission_required = 'dcim.add_site'
-    model = Site
-    form_class = SiteForm
-    template_name = 'dcim/site_edit.html'
-    cancel_url = 'dcim:site_list'
-
-
 class SiteEditView(PermissionRequiredMixin, ObjectEditView):
 class SiteEditView(PermissionRequiredMixin, ObjectEditView):
     permission_required = 'dcim.change_site'
     permission_required = 'dcim.change_site'
     model = Site
     model = Site
     form_class = SiteForm
     form_class = SiteForm
     template_name = 'dcim/site_edit.html'
     template_name = 'dcim/site_edit.html'
+    cancel_url = 'dcim:site_list'
 
 
 
 
 class SiteDeleteView(PermissionRequiredMixin, ObjectDeleteView):
 class SiteDeleteView(PermissionRequiredMixin, ObjectDeleteView):
@@ -139,18 +132,11 @@ class RackGroupListView(ObjectListView):
     template_name = 'dcim/rackgroup_list.html'
     template_name = 'dcim/rackgroup_list.html'
 
 
 
 
-class RackGroupAddView(PermissionRequiredMixin, ObjectAddView):
-    permission_required = 'dcim.add_rackgroup'
-    model = RackGroup
-    form_class = RackGroupForm
-    cancel_url = 'dcim:rackgroup_list'
-
-
 class RackGroupEditView(PermissionRequiredMixin, ObjectEditView):
 class RackGroupEditView(PermissionRequiredMixin, ObjectEditView):
     permission_required = 'dcim.change_rackgroup'
     permission_required = 'dcim.change_rackgroup'
     model = RackGroup
     model = RackGroup
     form_class = RackGroupForm
     form_class = RackGroupForm
-    return_url = 'dcim:rackgroup_list'
+    cancel_url = 'dcim:rackgroup_list'
 
 
 
 
 class RackGroupBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
 class RackGroupBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
@@ -191,19 +177,12 @@ def rack(request, pk):
     })
     })
 
 
 
 
-class RackAddView(PermissionRequiredMixin, ObjectAddView):
-    permission_required = 'dcim.add_rack'
-    model = Rack
-    form_class = RackForm
-    template_name = 'dcim/rack_edit.html'
-    cancel_url = 'dcim:rack_list'
-
-
 class RackEditView(PermissionRequiredMixin, ObjectEditView):
 class RackEditView(PermissionRequiredMixin, ObjectEditView):
     permission_required = 'dcim.change_rack'
     permission_required = 'dcim.change_rack'
     model = Rack
     model = Rack
     form_class = RackForm
     form_class = RackForm
     template_name = 'dcim/rack_edit.html'
     template_name = 'dcim/rack_edit.html'
+    cancel_url = 'dcim:rack_list'
 
 
 
 
 class RackDeleteView(PermissionRequiredMixin, ObjectDeleteView):
 class RackDeleteView(PermissionRequiredMixin, ObjectDeleteView):
@@ -256,18 +235,11 @@ class ManufacturerListView(ObjectListView):
     template_name = 'dcim/manufacturer_list.html'
     template_name = 'dcim/manufacturer_list.html'
 
 
 
 
-class ManufacturerAddView(PermissionRequiredMixin, ObjectAddView):
-    permission_required = 'dcim.add_manufacturer'
-    model = Manufacturer
-    form_class = ManufacturerForm
-    cancel_url = 'dcim:manufacturer_list'
-
-
 class ManufacturerEditView(PermissionRequiredMixin, ObjectEditView):
 class ManufacturerEditView(PermissionRequiredMixin, ObjectEditView):
     permission_required = 'dcim.change_manufacturer'
     permission_required = 'dcim.change_manufacturer'
     model = Manufacturer
     model = Manufacturer
     form_class = ManufacturerForm
     form_class = ManufacturerForm
-    return_url = 'dcim:manufacturer_list'
+    cancel_url = 'dcim:manufacturer_list'
 
 
 
 
 class ManufacturerBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
 class ManufacturerBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
@@ -317,17 +289,11 @@ def devicetype(request, pk):
     })
     })
 
 
 
 
-class DeviceTypeAddView(PermissionRequiredMixin, ObjectAddView):
-    permission_required = 'dcim.add_devicetype'
-    model = DeviceType
-    form_class = DeviceTypeForm
-    cancel_url = 'dcim:devicetype_list'
-
-
 class DeviceTypeEditView(PermissionRequiredMixin, ObjectEditView):
 class DeviceTypeEditView(PermissionRequiredMixin, ObjectEditView):
     permission_required = 'dcim.change_devicetype'
     permission_required = 'dcim.change_devicetype'
     model = DeviceType
     model = DeviceType
     form_class = DeviceTypeForm
     form_class = DeviceTypeForm
+    cancel_url = 'dcim:devicetype_list'
 
 
 
 
 class DeviceTypeDeleteView(PermissionRequiredMixin, ObjectDeleteView):
 class DeviceTypeDeleteView(PermissionRequiredMixin, ObjectDeleteView):
@@ -489,18 +455,12 @@ class DeviceRoleListView(ObjectListView):
     template_name = 'dcim/devicerole_list.html'
     template_name = 'dcim/devicerole_list.html'
 
 
 
 
-class DeviceRoleAddView(PermissionRequiredMixin, ObjectAddView):
-    permission_required = 'dcim.add_devicerole'
-    model = DeviceRole
-    form_class = DeviceRoleForm
-    cancel_url = 'dcim:devicerole_list'
-
-
 class DeviceRoleEditView(PermissionRequiredMixin, ObjectEditView):
 class DeviceRoleEditView(PermissionRequiredMixin, ObjectEditView):
     permission_required = 'dcim.change_devicerole'
     permission_required = 'dcim.change_devicerole'
     model = DeviceRole
     model = DeviceRole
     form_class = DeviceRoleForm
     form_class = DeviceRoleForm
-    return_url = 'dcim:devicerole_list'
+    success_url = 'dcim:devicerole_list'
+    cancel_url = 'dcim:devicerole_list'
 
 
 
 
 class DeviceRoleBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
 class DeviceRoleBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
@@ -568,20 +528,13 @@ def device(request, pk):
     })
     })
 
 
 
 
-class DeviceAddView(PermissionRequiredMixin, ObjectAddView):
-    permission_required = 'dcim.add_device'
-    model = Device
-    form_class = DeviceForm
-    template_name = 'dcim/device_edit.html'
-    cancel_url = 'dcim:device_list'
-    fields_initial = ['site', 'rack', 'position', 'face']
-
-
 class DeviceEditView(PermissionRequiredMixin, ObjectEditView):
 class DeviceEditView(PermissionRequiredMixin, ObjectEditView):
     permission_required = 'dcim.change_device'
     permission_required = 'dcim.change_device'
     model = Device
     model = Device
     form_class = DeviceForm
     form_class = DeviceForm
+    fields_initial = ['site', 'rack', 'position', 'face']
     template_name = 'dcim/device_edit.html'
     template_name = 'dcim/device_edit.html'
+    cancel_url = 'dcim:device_list'
 
 
 
 
 class DeviceDeleteView(PermissionRequiredMixin, ObjectDeleteView):
 class DeviceDeleteView(PermissionRequiredMixin, ObjectDeleteView):

+ 5 - 5
netbox/ipam/urls.py

@@ -4,7 +4,7 @@ from . import views
 
 
 urlpatterns = [
 urlpatterns = [
     url(r'^vrfs/$', views.VRFListView.as_view(), name='vrf_list'),
     url(r'^vrfs/$', views.VRFListView.as_view(), name='vrf_list'),
-    url(r'^vrfs/add/$', views.VRFAddView.as_view(), name='vrf_add'),
+    url(r'^vrfs/add/$', views.VRFEditView.as_view(), name='vrf_add'),
     url(r'^vrfs/import/$', views.VRFBulkImportView.as_view(), name='vrf_import'),
     url(r'^vrfs/import/$', views.VRFBulkImportView.as_view(), name='vrf_import'),
     url(r'^vrfs/edit/$', views.VRFBulkEditView.as_view(), name='vrf_bulk_edit'),
     url(r'^vrfs/edit/$', views.VRFBulkEditView.as_view(), name='vrf_bulk_edit'),
     url(r'^vrfs/delete/$', views.VRFBulkDeleteView.as_view(), name='vrf_bulk_delete'),
     url(r'^vrfs/delete/$', views.VRFBulkDeleteView.as_view(), name='vrf_bulk_delete'),
@@ -13,7 +13,7 @@ urlpatterns = [
     url(r'^vrfs/(?P<pk>\d+)/delete/$', views.VRFDeleteView.as_view(), name='vrf_delete'),
     url(r'^vrfs/(?P<pk>\d+)/delete/$', views.VRFDeleteView.as_view(), name='vrf_delete'),
 
 
     url(r'^aggregates/$', views.AggregateListView.as_view(), name='aggregate_list'),
     url(r'^aggregates/$', views.AggregateListView.as_view(), name='aggregate_list'),
-    url(r'^aggregates/add/$', views.AggregateAddView.as_view(), name='aggregate_add'),
+    url(r'^aggregates/add/$', views.AggregateEditView.as_view(), name='aggregate_add'),
     url(r'^aggregates/import/$', views.AggregateBulkImportView.as_view(), name='aggregate_import'),
     url(r'^aggregates/import/$', views.AggregateBulkImportView.as_view(), name='aggregate_import'),
     url(r'^aggregates/edit/$', views.AggregateBulkEditView.as_view(), name='aggregate_bulk_edit'),
     url(r'^aggregates/edit/$', views.AggregateBulkEditView.as_view(), name='aggregate_bulk_edit'),
     url(r'^aggregates/delete/$', views.AggregateBulkDeleteView.as_view(), name='aggregate_bulk_delete'),
     url(r'^aggregates/delete/$', views.AggregateBulkDeleteView.as_view(), name='aggregate_bulk_delete'),
@@ -22,7 +22,7 @@ urlpatterns = [
     url(r'^aggregates/(?P<pk>\d+)/delete/$', views.AggregateDeleteView.as_view(), name='aggregate_delete'),
     url(r'^aggregates/(?P<pk>\d+)/delete/$', views.AggregateDeleteView.as_view(), name='aggregate_delete'),
 
 
     url(r'^prefixes/$', views.PrefixListView.as_view(), name='prefix_list'),
     url(r'^prefixes/$', views.PrefixListView.as_view(), name='prefix_list'),
-    url(r'^prefixes/add/$', views.PrefixAddView.as_view(), name='prefix_add'),
+    url(r'^prefixes/add/$', views.PrefixEditView.as_view(), name='prefix_add'),
     url(r'^prefixes/import/$', views.PrefixBulkImportView.as_view(), name='prefix_import'),
     url(r'^prefixes/import/$', views.PrefixBulkImportView.as_view(), name='prefix_import'),
     url(r'^prefixes/edit/$', views.PrefixBulkEditView.as_view(), name='prefix_bulk_edit'),
     url(r'^prefixes/edit/$', views.PrefixBulkEditView.as_view(), name='prefix_bulk_edit'),
     url(r'^prefixes/delete/$', views.PrefixBulkDeleteView.as_view(), name='prefix_bulk_delete'),
     url(r'^prefixes/delete/$', views.PrefixBulkDeleteView.as_view(), name='prefix_bulk_delete'),
@@ -32,7 +32,7 @@ urlpatterns = [
     url(r'^prefixes/(?P<pk>\d+)/ip-addresses/$', views.prefix_ipaddresses, name='prefix_ipaddresses'),
     url(r'^prefixes/(?P<pk>\d+)/ip-addresses/$', views.prefix_ipaddresses, name='prefix_ipaddresses'),
 
 
     url(r'^ip-addresses/$', views.IPAddressListView.as_view(), name='ipaddress_list'),
     url(r'^ip-addresses/$', views.IPAddressListView.as_view(), name='ipaddress_list'),
-    url(r'^ip-addresses/add/$', views.IPAddressAddView.as_view(), name='ipaddress_add'),
+    url(r'^ip-addresses/add/$', views.IPAddressEditView.as_view(), name='ipaddress_add'),
     url(r'^ip-addresses/import/$', views.IPAddressBulkImportView.as_view(), name='ipaddress_import'),
     url(r'^ip-addresses/import/$', views.IPAddressBulkImportView.as_view(), name='ipaddress_import'),
     url(r'^ip-addresses/edit/$', views.IPAddressBulkEditView.as_view(), name='ipaddress_bulk_edit'),
     url(r'^ip-addresses/edit/$', views.IPAddressBulkEditView.as_view(), name='ipaddress_bulk_edit'),
     url(r'^ip-addresses/delete/$', views.IPAddressBulkDeleteView.as_view(), name='ipaddress_bulk_delete'),
     url(r'^ip-addresses/delete/$', views.IPAddressBulkDeleteView.as_view(), name='ipaddress_bulk_delete'),
@@ -41,7 +41,7 @@ urlpatterns = [
     url(r'^ip-addresses/(?P<pk>\d+)/delete/$', views.IPAddressDeleteView.as_view(), name='ipaddress_delete'),
     url(r'^ip-addresses/(?P<pk>\d+)/delete/$', views.IPAddressDeleteView.as_view(), name='ipaddress_delete'),
 
 
     url(r'^vlans/$', views.VLANListView.as_view(), name='vlan_list'),
     url(r'^vlans/$', views.VLANListView.as_view(), name='vlan_list'),
-    url(r'^vlans/add/$', views.VLANAddView.as_view(), name='vlan_add'),
+    url(r'^vlans/add/$', views.VLANEditView.as_view(), name='vlan_add'),
     url(r'^vlans/import/$', views.VLANBulkImportView.as_view(), name='vlan_import'),
     url(r'^vlans/import/$', views.VLANBulkImportView.as_view(), name='vlan_import'),
     url(r'^vlans/edit/$', views.VLANBulkEditView.as_view(), name='vlan_bulk_edit'),
     url(r'^vlans/edit/$', views.VLANBulkEditView.as_view(), name='vlan_bulk_edit'),
     url(r'^vlans/delete/$', views.VLANBulkDeleteView.as_view(), name='vlan_bulk_delete'),
     url(r'^vlans/delete/$', views.VLANBulkDeleteView.as_view(), name='vlan_bulk_delete'),

+ 9 - 40
netbox/ipam/views.py

@@ -8,8 +8,8 @@ from django.shortcuts import get_object_or_404, render
 
 
 from dcim.models import Device
 from dcim.models import Device
 from utilities.paginator import EnhancedPaginator
 from utilities.paginator import EnhancedPaginator
-from utilities.views import BulkImportView, BulkEditView, BulkDeleteView, ObjectListView, ObjectAddView,\
-    ObjectEditView, ObjectDeleteView
+from utilities.views import BulkImportView, BulkEditView, BulkDeleteView, ObjectListView, ObjectEditView,\
+    ObjectDeleteView
 
 
 from .filters import AggregateFilter, PrefixFilter, IPAddressFilter, VLANFilter, VRFFilter
 from .filters import AggregateFilter, PrefixFilter, IPAddressFilter, VLANFilter, VRFFilter
 from .forms import AggregateForm, AggregateImportForm, AggregateBulkEditForm, AggregateBulkDeleteForm,\
 from .forms import AggregateForm, AggregateImportForm, AggregateBulkEditForm, AggregateBulkDeleteForm,\
@@ -61,17 +61,11 @@ def vrf(request, pk):
     })
     })
 
 
 
 
-class VRFAddView(PermissionRequiredMixin, ObjectAddView):
-    permission_required = 'ipam.add_vrf'
-    model = VRF
-    form_class = VRFForm
-    cancel_url = 'ipam:vrf_list'
-
-
 class VRFEditView(PermissionRequiredMixin, ObjectEditView):
 class VRFEditView(PermissionRequiredMixin, ObjectEditView):
     permission_required = 'ipam.change_vrf'
     permission_required = 'ipam.change_vrf'
     model = VRF
     model = VRF
     form_class = VRFForm
     form_class = VRFForm
+    cancel_url = 'ipam:vrf_list'
 
 
 
 
 class VRFDeleteView(PermissionRequiredMixin, ObjectDeleteView):
 class VRFDeleteView(PermissionRequiredMixin, ObjectDeleteView):
@@ -149,17 +143,11 @@ def aggregate(request, pk):
     })
     })
 
 
 
 
-class AggregateAddView(PermissionRequiredMixin, ObjectAddView):
-    permission_required = 'ipam.add_aggregate'
-    model = Aggregate
-    form_class = AggregateForm
-    cancel_url = 'ipam:aggregate_list'
-
-
 class AggregateEditView(PermissionRequiredMixin, ObjectEditView):
 class AggregateEditView(PermissionRequiredMixin, ObjectEditView):
     permission_required = 'ipam.change_aggregate'
     permission_required = 'ipam.change_aggregate'
     model = Aggregate
     model = Aggregate
     form_class = AggregateForm
     form_class = AggregateForm
+    cancel_url = 'ipam:aggregate_list'
 
 
 
 
 class AggregateDeleteView(PermissionRequiredMixin, ObjectDeleteView):
 class AggregateDeleteView(PermissionRequiredMixin, ObjectDeleteView):
@@ -262,18 +250,12 @@ def prefix(request, pk):
     })
     })
 
 
 
 
-class PrefixAddView(PermissionRequiredMixin, ObjectAddView):
-    permission_required = 'ipam.add_prefix'
-    model = Prefix
-    form_class = PrefixForm
-    cancel_url = 'ipam:prefix_list'
-    fields_initial = ['site', 'vrf', 'prefix']
-
-
 class PrefixEditView(PermissionRequiredMixin, ObjectEditView):
 class PrefixEditView(PermissionRequiredMixin, ObjectEditView):
     permission_required = 'ipam.change_prefix'
     permission_required = 'ipam.change_prefix'
     model = Prefix
     model = Prefix
     form_class = PrefixForm
     form_class = PrefixForm
+    fields_initial = ['site', 'vrf', 'prefix']
+    cancel_url = 'ipam:prefix_list'
 
 
 
 
 class PrefixDeleteView(PermissionRequiredMixin, ObjectDeleteView):
 class PrefixDeleteView(PermissionRequiredMixin, ObjectDeleteView):
@@ -369,20 +351,13 @@ def ipaddress(request, pk):
     })
     })
 
 
 
 
-class IPAddressAddView(PermissionRequiredMixin, ObjectAddView):
-    permission_required = 'ipam.add_ipaddress'
-    model = IPAddress
-    form_class = IPAddressForm
-    template_name = 'ipam/ipaddress_edit.html'
-    cancel_url = 'ipam:ipaddress_list'
-    fields_initial = ['ipaddress']
-
-
 class IPAddressEditView(PermissionRequiredMixin, ObjectEditView):
 class IPAddressEditView(PermissionRequiredMixin, ObjectEditView):
     permission_required = 'ipam.change_ipaddress'
     permission_required = 'ipam.change_ipaddress'
     model = IPAddress
     model = IPAddress
     form_class = IPAddressForm
     form_class = IPAddressForm
+    fields_initial = ['ipaddress']
     template_name = 'ipam/ipaddress_edit.html'
     template_name = 'ipam/ipaddress_edit.html'
+    cancel_url = 'ipam:ipaddress_list'
 
 
 
 
 class IPAddressDeleteView(PermissionRequiredMixin, ObjectDeleteView):
 class IPAddressDeleteView(PermissionRequiredMixin, ObjectDeleteView):
@@ -462,17 +437,11 @@ def vlan(request, pk):
     })
     })
 
 
 
 
-class VLANAddView(PermissionRequiredMixin, ObjectAddView):
-    permission_required = 'ipam.add_vlan'
-    model = VLAN
-    form_class = VLANForm
-    cancel_url = 'ipam:vlan_list'
-
-
 class VLANEditView(PermissionRequiredMixin, ObjectEditView):
 class VLANEditView(PermissionRequiredMixin, ObjectEditView):
     permission_required = 'ipam.change_vlan'
     permission_required = 'ipam.change_vlan'
     model = VLAN
     model = VLAN
     form_class = VLANForm
     form_class = VLANForm
+    cancel_url = 'ipam:vlan_list'
 
 
 
 
 class VLANDeleteView(PermissionRequiredMixin, ObjectDeleteView):
 class VLANDeleteView(PermissionRequiredMixin, ObjectDeleteView):

+ 25 - 50
netbox/utilities/views.py

@@ -75,48 +75,13 @@ class ObjectListView(View):
         return self.queryset
         return self.queryset
 
 
 
 
-class ObjectAddView(View):
-    model = None
-    form_class = None
-    template_name = 'utilities/obj_edit.html'
-    cancel_url = None
-    fields_initial = []
-
-    def get(self, request):
-
-        initial = {k: request.GET.get(k) for k in self.fields_initial}
-        form = self.form_class(initial=initial)
-
-        return render(request, self.template_name, {
-            'form': form,
-            'obj_type': self.model._meta.verbose_name,
-            'cancel_url': reverse(self.cancel_url),
-        })
-
-    def post(self, request):
-
-        form = self.form_class(request.POST)
-        if form.is_valid():
-            obj = form.save()
-            messages.success(request, 'Added new {} <a href="{}">{}</a>'.format(self.model._meta.verbose_name,
-                                                                                obj.get_absolute_url(), obj))
-            if '_addanother' in request.POST:
-                return redirect(request.path)
-            else:
-                return redirect(obj.get_absolute_url())
-
-        return render(request, self.template_name, {
-            'form': form,
-            'obj_type': self.model._meta.verbose_name,
-            'cancel_url': reverse(self.cancel_url),
-        })
-
-
 class ObjectEditView(View):
 class ObjectEditView(View):
     model = None
     model = None
     form_class = None
     form_class = None
+    fields_initial = []
     template_name = 'utilities/obj_edit.html'
     template_name = 'utilities/obj_edit.html'
-    return_url = None
+    success_url = None
+    cancel_url = None
 
 
     def get_object(self, kwargs):
     def get_object(self, kwargs):
         # Look up object by slug if one has been provided. Otherwise, use PK.
         # Look up object by slug if one has been provided. Otherwise, use PK.
@@ -127,36 +92,46 @@ class ObjectEditView(View):
 
 
     def get(self, request, *args, **kwargs):
     def get(self, request, *args, **kwargs):
 
 
-        obj = self.get_object(kwargs)
-        form = self.form_class(instance=obj)
+        if kwargs:
+            obj = self.get_object(kwargs)
+            form = self.form_class(instance=obj)
+        else:
+            obj = None
+            form = self.form_class(initial={k: request.GET.get(k) for k in self.fields_initial})
 
 
         return render(request, self.template_name, {
         return render(request, self.template_name, {
             'obj': obj,
             'obj': obj,
-            'form': form,
             'obj_type': self.model._meta.verbose_name,
             'obj_type': self.model._meta.verbose_name,
-            'cancel_url': reverse(self.return_url) if self.return_url else obj.get_absolute_url(),
+            'form': form,
+            'cancel_url': reverse(self.cancel_url) if self.cancel_url else obj.get_absolute_url(),
         })
         })
 
 
     def post(self, request, *args, **kwargs):
     def post(self, request, *args, **kwargs):
 
 
-        obj = self.get_object(kwargs)
+        # Validate object if editing an existing object
+        obj = self.get_object(kwargs) if kwargs else None
+
         form = self.form_class(request.POST, instance=obj)
         form = self.form_class(request.POST, instance=obj)
         if form.is_valid():
         if form.is_valid():
-            obj = form.save()
-            messages.success(request, 'Modified {} <a href="{}">{}</a>'.format(self.model._meta.verbose_name,
-                                                                               obj.get_absolute_url(), obj))
+            obj = form.save(commit=False)
+            obj_created = not obj.pk
+            obj.save()
+            messages.success(request, '{} {} <a href="{}">{}</a>'.format('Created' if obj_created else 'Modified',
+                                                                         self.model._meta.verbose_name,
+                                                                         obj.get_absolute_url(),
+                                                                         obj))
             if '_addanother' in request.POST:
             if '_addanother' in request.POST:
                 return redirect(request.path)
                 return redirect(request.path)
-            elif self.return_url:
-                return redirect(self.return_url)
+            elif self.success_url:
+                return redirect(self.success_url)
             else:
             else:
                 return redirect(obj.get_absolute_url())
                 return redirect(obj.get_absolute_url())
 
 
         return render(request, self.template_name, {
         return render(request, self.template_name, {
             'obj': obj,
             'obj': obj,
-            'form': form,
             'obj_type': self.model._meta.verbose_name,
             'obj_type': self.model._meta.verbose_name,
-            'cancel_url': reverse(self.return_url) if self.return_url else obj.get_absolute_url(),
+            'form': form,
+            'cancel_url': reverse(self.cancel_url) if self.cancel_url else obj.get_absolute_url(),
         })
         })