Răsfoiți Sursa

Started on #4325 (WIP)

Jeremy Stretch 6 ani în urmă
părinte
comite
ad9dfec894
4 a modificat fișierele cu 86 adăugiri și 1 ștergeri
  1. 64 0
      netbox/dcim/forms.py
  2. 13 0
      netbox/dcim/models/__init__.py
  3. 1 0
      netbox/dcim/urls.py
  4. 8 1
      netbox/dcim/views.py

+ 64 - 0
netbox/dcim/forms.py

@@ -829,6 +829,70 @@ class RackReservationForm(BootstrapMixin, TenancyForm, forms.ModelForm):
         return unit_choices
 
 
+class RackReservationCSVForm(forms.ModelForm):
+    site = forms.ModelChoiceField(
+        queryset=Site.objects.all(),
+        to_field_name='name',
+        help_text='Name of parent site',
+        error_messages={
+            'invalid_choice': 'Invalid site name.',
+        }
+    )
+    rack_group = forms.ModelChoiceField(
+        queryset=RackGroup.objects.all(),
+        to_field_name='name',
+        required=False,
+        help_text='Name of rack group',
+        error_messages={
+            'invalid_choice': 'Invalid rack group name.',
+        }
+    )
+    rack = forms.CharField(
+        required=True,
+        help_text='Name of parent rack'
+    )
+    units = forms.CharField(
+        required=True,
+        help_text='Rack units'
+    )
+    tenant = forms.ModelChoiceField(
+        queryset=Tenant.objects.all(),
+        required=False,
+        to_field_name='name',
+        help_text='Name of assigned tenant',
+        error_messages={
+            'invalid_choice': 'Tenant not found.',
+        }
+    )
+
+    class Meta:
+        model = RackReservation
+        # fields = RackReservation.csv_headers
+        fields = ['site', 'rack_group', 'rack', 'units', 'tenant', 'description']  # Can't set user
+        help_texts = {
+        }
+
+    def clean(self):
+
+        super().clean()
+
+        site = self.cleaned_data.get('site')
+        rack_group = self.cleaned_data.get('rack_group')
+        rack_name = self.cleaned_data.get('rack')
+
+        # Validate rack
+        if site and rack_group and rack_name:
+            try:
+                self.instance.rack = Rack.objects.get(site=site, group__name=rack_group, name=rack_name)
+            except Rack.DoesNotExist:
+                raise forms.ValidationError("Rack {} not found in site {} group {}".format(rack_name, site, rack_group))
+        elif site and rack_name:
+            try:
+                self.instance.rack = Rack.objects.get(site=site, group__isnull=True, name=rack_name)
+            except Rack.DoesNotExist:
+                raise forms.ValidationError("Rack {} not found in site {} (no group)".format(rack_name, site))
+
+
 class RackReservationBulkEditForm(BootstrapMixin, BulkEditForm):
     pk = forms.ModelMultipleChoiceField(
         queryset=RackReservation.objects.all(),

+ 13 - 0
netbox/dcim/models/__init__.py

@@ -761,6 +761,8 @@ class RackReservation(ChangeLoggedModel):
         max_length=100
     )
 
+    csv_headers = ['site', 'rack_group', 'rack', 'units', 'tenant', 'user', 'description']
+
     class Meta:
         ordering = ['created']
 
@@ -793,6 +795,17 @@ class RackReservation(ChangeLoggedModel):
                     )
                 })
 
+    def to_csv(self):
+        return (
+            self.rack.site.name,
+            self.rack.group if self.rack.group else None,
+            self.rack.name,
+            ','.join([str(u) for u in self.units]),
+            self.tenant.name if self.tenant else None,
+            self.user.username,
+            self.description
+        )
+
     @property
     def unit_list(self):
         """

+ 1 - 0
netbox/dcim/urls.py

@@ -51,6 +51,7 @@ urlpatterns = [
 
     # Rack reservations
     path('rack-reservations/', views.RackReservationListView.as_view(), name='rackreservation_list'),
+    path('rack-reservations/import/', views.RackReservationImportView.as_view(), name='rackreservation_import'),
     path('rack-reservations/edit/', views.RackReservationBulkEditView.as_view(), name='rackreservation_bulk_edit'),
     path('rack-reservations/delete/', views.RackReservationBulkDeleteView.as_view(), name='rackreservation_bulk_delete'),
     path('rack-reservations/<int:pk>/edit/', views.RackReservationEditView.as_view(), name='rackreservation_edit'),

+ 8 - 1
netbox/dcim/views.py

@@ -470,7 +470,7 @@ class RackReservationListView(PermissionRequiredMixin, ObjectListView):
     filterset = filters.RackReservationFilterSet
     filterset_form = forms.RackReservationFilterForm
     table = tables.RackReservationTable
-    action_buttons = ()
+    action_buttons = ('export',)
 
 
 class RackReservationCreateView(PermissionRequiredMixin, ObjectEditView):
@@ -500,6 +500,13 @@ class RackReservationDeleteView(PermissionRequiredMixin, ObjectDeleteView):
         return obj.rack.get_absolute_url()
 
 
+class RackReservationImportView(PermissionRequiredMixin, BulkImportView):
+    permission_required = 'dcim.add_rackreservation'
+    model_form = forms.RackReservationCSVForm
+    table = tables.RackReservationTable
+    default_return_url = 'dcim:rackreservation_list'
+
+
 class RackReservationBulkEditView(PermissionRequiredMixin, BulkEditView):
     permission_required = 'dcim.change_rackreservation'
     queryset = RackReservation.objects.prefetch_related('rack', 'user')