Skip to content

Commit

Permalink
Closes #5003: CSV import now accepts slug values for choice fields
Browse files Browse the repository at this point in the history
  • Loading branch information
jeremystretch committed Sep 18, 2020
1 parent 70ec5b9 commit 0cc2a6b
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 39 deletions.
1 change: 1 addition & 0 deletions docs/release-notes/version-2.10.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

* [#1692](https://github.com/netbox-community/netbox/issues/1692) - Allow assigment of inventory items to parent items in web UI
* [#4956](https://github.com/netbox-community/netbox/issues/4956) - Include inventory items on primary device view
* [#5003](https://github.com/netbox-community/netbox/issues/5003) - CSV import now accepts slug values for choice fields
* [#5146](https://github.com/netbox-community/netbox/issues/5146) - Add custom fields support for cables, power panels, rack reservations, and virtual chassis

### Other Changes
Expand Down
24 changes: 12 additions & 12 deletions netbox/dcim/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -983,9 +983,9 @@ def setUpTestData(cls):

cls.csv_data = (
"device_role,manufacturer,device_type,status,name,site,rack_group,rack,position,face",
"Device Role 1,Manufacturer 1,Device Type 1,Active,Device 4,Site 1,Rack Group 1,Rack 1,10,Front",
"Device Role 1,Manufacturer 1,Device Type 1,Active,Device 5,Site 1,Rack Group 1,Rack 1,20,Front",
"Device Role 1,Manufacturer 1,Device Type 1,Active,Device 6,Site 1,Rack Group 1,Rack 1,30,Front",
"Device Role 1,Manufacturer 1,Device Type 1,active,Device 4,Site 1,Rack Group 1,Rack 1,10,front",
"Device Role 1,Manufacturer 1,Device Type 1,active,Device 5,Site 1,Rack Group 1,Rack 1,20,front",
"Device Role 1,Manufacturer 1,Device Type 1,active,Device 6,Site 1,Rack Group 1,Rack 1,30,front",
)

cls.bulk_edit_data = {
Expand Down Expand Up @@ -1267,9 +1267,9 @@ def setUpTestData(cls):

cls.csv_data = (
"device,name,type",
"Device 1,Interface 4,1000BASE-T (1GE)",
"Device 1,Interface 5,1000BASE-T (1GE)",
"Device 1,Interface 6,1000BASE-T (1GE)",
"Device 1,Interface 4,1000base-t",
"Device 1,Interface 5,1000base-t",
"Device 1,Interface 6,1000base-t",
)


Expand Down Expand Up @@ -1326,9 +1326,9 @@ def setUpTestData(cls):

cls.csv_data = (
"device,name,type,rear_port,rear_port_position",
"Device 1,Front Port 4,8P8C,Rear Port 4,1",
"Device 1,Front Port 5,8P8C,Rear Port 5,1",
"Device 1,Front Port 6,8P8C,Rear Port 6,1",
"Device 1,Front Port 4,8p8c,Rear Port 4,1",
"Device 1,Front Port 5,8p8c,Rear Port 5,1",
"Device 1,Front Port 6,8p8c,Rear Port 6,1",
)


Expand Down Expand Up @@ -1372,9 +1372,9 @@ def setUpTestData(cls):

cls.csv_data = (
"device,name,type,positions",
"Device 1,Rear Port 4,8P8C,1",
"Device 1,Rear Port 5,8P8C,1",
"Device 1,Rear Port 6,8P8C,1",
"Device 1,Rear Port 4,8p8c,1",
"Device 1,Rear Port 5,8p8c,1",
"Device 1,Rear Port 6,8p8c,1",
)


Expand Down
24 changes: 12 additions & 12 deletions netbox/ipam/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -194,9 +194,9 @@ def setUpTestData(cls):

cls.csv_data = (
"vrf,prefix,status",
"VRF 1,10.4.0.0/16,Active",
"VRF 1,10.5.0.0/16,Active",
"VRF 1,10.6.0.0/16,Active",
"VRF 1,10.4.0.0/16,active",
"VRF 1,10.5.0.0/16,active",
"VRF 1,10.6.0.0/16,active",
)

cls.bulk_edit_data = {
Expand Down Expand Up @@ -244,9 +244,9 @@ def setUpTestData(cls):

cls.csv_data = (
"vrf,address,status",
"VRF 1,192.0.2.4/24,Active",
"VRF 1,192.0.2.5/24,Active",
"VRF 1,192.0.2.6/24,Active",
"VRF 1,192.0.2.4/24,active",
"VRF 1,192.0.2.5/24,active",
"VRF 1,192.0.2.6/24,active",
)

cls.bulk_edit_data = {
Expand Down Expand Up @@ -334,9 +334,9 @@ def setUpTestData(cls):

cls.csv_data = (
"vid,name,status",
"104,VLAN104,Active",
"105,VLAN105,Active",
"106,VLAN106,Active",
"104,VLAN104,active",
"105,VLAN105,active",
"106,VLAN106,active",
)

cls.bulk_edit_data = {
Expand Down Expand Up @@ -393,9 +393,9 @@ def setUpTestData(cls):

cls.csv_data = (
"device,name,protocol,port,description",
"Device 1,Service 1,TCP,1,First service",
"Device 1,Service 2,TCP,2,Second service",
"Device 1,Service 3,UDP,3,Third service",
"Device 1,Service 1,tcp,1,First service",
"Device 1,Service 2,tcp,2,Second service",
"Device 1,Service 3,udp,3,Third service",
)

cls.bulk_edit_data = {
Expand Down
11 changes: 7 additions & 4 deletions netbox/templates/utilities/obj_bulk_import.html
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ <h1>{% block title %}{{ obj_type|bettertitle }} Bulk Import{% endblock %}</h1>
{% endif %}
</td>
<td>
{% if field.choice_values %}
{% if field.STATIC_CHOICES %}
<button type="button" class="btn btn-primary btn-xs pull-right" data-toggle="modal" data-target="#{{ name }}_choices">
<i class="fa fa-question"></i>
</button>
Expand All @@ -77,9 +77,12 @@ <h1>{% block title %}{{ obj_type|bettertitle }} Bulk Import{% endblock %}</h1>
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title"><code>{{ name }}</code> Choices</h4>
</div>
<div class="modal-body">
<ul>{% for value, label in field.choices %}{% if value %}<li>{{ value }}</li>{% endif %}{% endfor %}</ul>
</div>
<table class="table table-striped modal-body">
<tr><th>Import Value</th><th>Label</th></tr>
{% for value, label in field.choices %}
{% if value %}<tr><td><samp>{{ value }}</samp></td><td>{{ label }}</td></tr>{% endif %}
{% endfor %}
</table>
</div>
</div>
</div>
Expand Down
15 changes: 4 additions & 11 deletions netbox/utilities/forms/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,18 +117,11 @@ class CSVChoiceField(forms.ChoiceField):
"""
Invert the provided set of choices to take the human-friendly label as input, and return the database value.
"""
def __init__(self, choices, *args, **kwargs):
super().__init__(choices=choices, *args, **kwargs)
self.choices = [(label, label) for value, label in unpack_grouped_choices(choices)]
self.choice_values = {label: value for value, label in unpack_grouped_choices(choices)}
STATIC_CHOICES = True

def clean(self, value):
value = super().clean(value)
if not value:
return ''
if value not in self.choice_values:
raise forms.ValidationError("Invalid choice: {}".format(value))
return self.choice_values[value]
def __init__(self, *, choices=(), **kwargs):
super().__init__(choices=choices, **kwargs)
self.choices = unpack_grouped_choices(choices)


class CSVModelChoiceField(forms.ModelChoiceField):
Expand Down

0 comments on commit 0cc2a6b

Please sign in to comment.