Browse Source

Merge branch 'develop' into v2-develop

Conflicts:
	netbox/ipam/forms.py
Jeremy Stretch 8 years ago
parent
commit
616f109671
3 changed files with 20 additions and 71 deletions
  1. 1 61
      netbox/ipam/forms.py
  2. 7 6
      netbox/project-static/js/forms.js
  3. 12 4
      netbox/utilities/views.py

+ 1 - 61
netbox/ipam/forms.py

@@ -236,7 +236,6 @@ class PrefixFromCSVForm(forms.ModelForm):
                     self.add_error('vlan_vid', "Invalid global VLAN ID ({}).".format(vlan_vid))
                     self.add_error('vlan_vid', "Invalid global VLAN ID ({}).".format(vlan_vid))
             except VLAN.MultipleObjectsReturned:
             except VLAN.MultipleObjectsReturned:
                 self.add_error('vlan_vid', "Multiple VLANs found ({} - VID {})".format(site, vlan_vid))
                 self.add_error('vlan_vid', "Multiple VLANs found ({} - VID {})".format(site, vlan_vid))
-            self.instance.vlan = vlan
 
 
     def save(self, *args, **kwargs):
     def save(self, *args, **kwargs):
 
 
@@ -316,7 +315,7 @@ class IPAddressForm(BootstrapMixin, ReturnURLForm, CustomFieldForm):
     interface_rack = forms.ModelChoiceField(
     interface_rack = forms.ModelChoiceField(
         queryset=Rack.objects.all(), required=False, label='Rack', widget=APISelect(
         queryset=Rack.objects.all(), required=False, label='Rack', widget=APISelect(
             api_url='/api/dcim/racks/?site_id={{interface_site}}', display_field='display_name',
             api_url='/api/dcim/racks/?site_id={{interface_site}}', display_field='display_name',
-            attrs={'filter-for': 'interface_device'}
+            attrs={'filter-for': 'interface_device', 'nullable': 'true'}
         )
         )
     )
     )
     interface_device = forms.ModelChoiceField(
     interface_device = forms.ModelChoiceField(
@@ -429,65 +428,6 @@ class IPAddressBulkAddForm(BootstrapMixin, CustomFieldForm):
         fields = ['address_pattern', 'vrf', 'tenant', 'status', 'description']
         fields = ['address_pattern', 'vrf', 'tenant', 'status', 'description']
 
 
 
 
-class IPAddressAssignForm(BootstrapMixin, forms.Form):
-    site = forms.ModelChoiceField(
-        queryset=Site.objects.all(),
-        label='Site',
-        required=False,
-        widget=forms.Select(
-            attrs={'filter-for': 'rack'}
-        )
-    )
-    rack = forms.ModelChoiceField(
-        queryset=Rack.objects.all(),
-        label='Rack',
-        required=False,
-        widget=APISelect(
-            api_url='/api/dcim/racks/?site_id={{site}}',
-            display_field='display_name',
-            attrs={'filter-for': 'device', 'nullable': 'true'}
-        )
-    )
-    device = forms.ModelChoiceField(
-        queryset=Device.objects.all(),
-        label='Device',
-        required=False,
-        widget=APISelect(
-            api_url='/api/dcim/devices/?site_id={{site}}&rack_id={{rack}}',
-            display_field='display_name',
-            attrs={'filter-for': 'interface'}
-        )
-    )
-    livesearch = forms.CharField(
-        required=False,
-        label='Device',
-        widget=Livesearch(
-            query_key='q',
-            query_url='dcim-api:device-list',
-            field_to_update='device'
-        )
-    )
-    interface = forms.ModelChoiceField(
-        queryset=Interface.objects.all(),
-        label='Interface',
-        widget=APISelect(
-            api_url='/api/dcim/interfaces/?device_id={{device}}'
-        )
-    )
-    set_as_primary = forms.BooleanField(
-        label='Set as primary IP for device',
-        required=False
-    )
-
-    def __init__(self, *args, **kwargs):
-
-        super(IPAddressAssignForm, self).__init__(*args, **kwargs)
-
-        self.fields['rack'].choices = []
-        self.fields['device'].choices = []
-        self.fields['interface'].choices = []
-
-
 class IPAddressFromCSVForm(forms.ModelForm):
 class IPAddressFromCSVForm(forms.ModelForm):
     vrf = forms.ModelChoiceField(queryset=VRF.objects.all(), required=False, to_field_name='rd',
     vrf = forms.ModelChoiceField(queryset=VRF.objects.all(), required=False, to_field_name='rd',
                                  error_messages={'invalid_choice': 'VRF not found.'})
                                  error_messages={'invalid_choice': 'VRF not found.'})

+ 7 - 6
netbox/project-static/js/forms.js

@@ -88,20 +88,21 @@ $(document).ready(function() {
             // Determine the filter fields needed to make an API call
             // Determine the filter fields needed to make an API call
             var filter_regex = /\{\{([a-z_]+)\}\}/g;
             var filter_regex = /\{\{([a-z_]+)\}\}/g;
             var match;
             var match;
+            var rendered_url = api_url;
             while (match = filter_regex.exec(api_url)) {
             while (match = filter_regex.exec(api_url)) {
                 var filter_field = $('#id_' + match[1]);
                 var filter_field = $('#id_' + match[1]);
                 if (filter_field.val()) {
                 if (filter_field.val()) {
-                    api_url = api_url.replace(match[0], filter_field.val());
-                } else if ($(this).attr('nullable') == 'true') {
-                    api_url = api_url.replace(match[0], '0');
+                    rendered_url = rendered_url.replace(match[0], filter_field.val());
+                } else if (filter_field.attr('nullable') == 'true') {
+                    rendered_url = rendered_url.replace(match[0], '0');
                 }
                 }
             }
             }
 
 
             // If all URL variables have been replaced, make the API call
             // If all URL variables have been replaced, make the API call
-            if (api_url.search('{{') < 0) {
-                console.log(child_name + ": Fetching " + api_url);
+            if (rendered_url.search('{{') < 0) {
+                console.log(child_name + ": Fetching " + rendered_url);
                 $.ajax({
                 $.ajax({
-                    url: api_url,
+                    url: rendered_url,
                     dataType: 'json',
                     dataType: 'json',
                     success: function(response, status) {
                     success: function(response, status) {
                         $.each(response.results, function(index, choice) {
                         $.each(response.results, function(index, choice) {

+ 12 - 4
netbox/utilities/views.py

@@ -329,13 +329,21 @@ class BulkAddView(View):
             new_objs = []
             new_objs = []
             try:
             try:
                 with transaction.atomic():
                 with transaction.atomic():
+                    # Validate and save each object individually
                     for value in pattern:
                     for value in pattern:
                         model_form_data[pattern_target] = value
                         model_form_data[pattern_target] = value
                         model_form = self.model_form(model_form_data)
                         model_form = self.model_form(model_form_data)
-                        obj = model_form.save()
-                        new_objs.append(obj)
-            except ValidationError as e:
-                form.add_error(None, e)
+                        if model_form.is_valid():
+                            obj = model_form.save()
+                            new_objs.append(obj)
+                        else:
+                            for error in model_form.errors.as_data().values():
+                                form.add_error(None, error)
+                    # Abort the creation of all objects if errors exist
+                    if form.errors:
+                        raise ValidationError("Validation of one or more model forms failed.")
+            except ValidationError:
+                pass
 
 
             if not form.errors:
             if not form.errors:
                 msg = u"Added {} {}".format(len(new_objs), model._meta.verbose_name_plural)
                 msg = u"Added {} {}".format(len(new_objs), model._meta.verbose_name_plural)