mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-23 04:22:01 -06:00
11955 remove csvdatafield csvfilefield
This commit is contained in:
parent
43bba935c3
commit
5b81986bb3
@ -14,8 +14,6 @@ from utilities.utils import content_type_identifier
|
||||
__all__ = (
|
||||
'CSVChoiceField',
|
||||
'CSVContentTypeField',
|
||||
'CSVDataField',
|
||||
'CSVFileField',
|
||||
'CSVModelChoiceField',
|
||||
'CSVModelMultipleChoiceField',
|
||||
'CSVMultipleChoiceField',
|
||||
@ -24,90 +22,6 @@ __all__ = (
|
||||
)
|
||||
|
||||
|
||||
class CSVDataField(forms.CharField):
|
||||
"""
|
||||
A CharField (rendered as a Textarea) which accepts CSV-formatted data. It returns data as a two-tuple: The first
|
||||
item is a dictionary of column headers, mapping field names to the attribute by which they match a related object
|
||||
(where applicable). The second item is a list of dictionaries, each representing a discrete row of CSV data.
|
||||
|
||||
:param from_form: The form from which the field derives its validation rules.
|
||||
"""
|
||||
widget = forms.Textarea
|
||||
|
||||
def __init__(self, from_form, *args, **kwargs):
|
||||
|
||||
form = from_form()
|
||||
self.model = form.Meta.model
|
||||
self.fields = form.fields
|
||||
self.required_fields = [
|
||||
name for name, field in form.fields.items() if field.required
|
||||
]
|
||||
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
self.strip = False
|
||||
if not self.label:
|
||||
self.label = ''
|
||||
if not self.initial:
|
||||
self.initial = ','.join(self.required_fields) + '\n'
|
||||
if not self.help_text:
|
||||
self.help_text = _('Enter the list of column headers followed by one line per record to be imported, using '
|
||||
'commas to separate values. Multi-line data and values containing commas may be wrapped '
|
||||
'in double quotes.')
|
||||
|
||||
def to_python(self, value):
|
||||
reader = csv.reader(StringIO(value.strip()))
|
||||
|
||||
return parse_csv(reader)
|
||||
|
||||
def validate(self, value):
|
||||
headers, records = value
|
||||
validate_csv(headers, self.fields, self.required_fields)
|
||||
|
||||
return value
|
||||
|
||||
|
||||
class CSVFileField(forms.FileField):
|
||||
"""
|
||||
A FileField (rendered as a file input button) which accepts a file containing CSV-formatted data. It returns
|
||||
data as a two-tuple: The first item is a dictionary of column headers, mapping field names to the attribute
|
||||
by which they match a related object (where applicable). The second item is a list of dictionaries, each
|
||||
representing a discrete row of CSV data.
|
||||
|
||||
:param from_form: The form from which the field derives its validation rules.
|
||||
"""
|
||||
|
||||
def __init__(self, from_form, *args, **kwargs):
|
||||
|
||||
form = from_form()
|
||||
self.model = form.Meta.model
|
||||
self.fields = form.fields
|
||||
self.required_fields = [
|
||||
name for name, field in form.fields.items() if field.required
|
||||
]
|
||||
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
def to_python(self, file):
|
||||
if file is None:
|
||||
return None
|
||||
|
||||
csv_str = file.read().decode('utf-8').strip()
|
||||
reader = csv.reader(StringIO(csv_str))
|
||||
headers, records = parse_csv(reader)
|
||||
|
||||
return headers, records
|
||||
|
||||
def validate(self, value):
|
||||
if value is None:
|
||||
return None
|
||||
|
||||
headers, records = value
|
||||
validate_csv(headers, self.fields, self.required_fields)
|
||||
|
||||
return value
|
||||
|
||||
|
||||
class CSVChoicesMixin:
|
||||
STATIC_CHOICES = True
|
||||
|
||||
|
@ -1,10 +1,8 @@
|
||||
from django import forms
|
||||
from django.test import TestCase
|
||||
|
||||
from ipam.forms import IPAddressImportForm
|
||||
from utilities.choices import ImportFormatChoices
|
||||
from utilities.forms.bulk_import import ImportForm
|
||||
from utilities.forms.fields import CSVDataField
|
||||
from utilities.forms.utils import expand_alphanumeric_pattern, expand_ipaddress_pattern
|
||||
|
||||
|
||||
@ -287,88 +285,6 @@ class ExpandAlphanumeric(TestCase):
|
||||
sorted(expand_alphanumeric_pattern('r[a,,b]a'))
|
||||
|
||||
|
||||
class CSVDataFieldTest(TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.field = CSVDataField(from_form=IPAddressImportForm)
|
||||
|
||||
def test_clean(self):
|
||||
input = """
|
||||
address,status,vrf
|
||||
192.0.2.1/32,Active,Test VRF
|
||||
"""
|
||||
output = (
|
||||
{'address': None, 'status': None, 'vrf': None},
|
||||
[{'address': '192.0.2.1/32', 'status': 'Active', 'vrf': 'Test VRF'}]
|
||||
)
|
||||
self.assertEqual(self.field.clean(input), output)
|
||||
|
||||
def test_clean_invalid_header(self):
|
||||
input = """
|
||||
address,status,vrf,xxx
|
||||
192.0.2.1/32,Active,Test VRF,123
|
||||
"""
|
||||
with self.assertRaises(forms.ValidationError):
|
||||
self.field.clean(input)
|
||||
|
||||
def test_clean_missing_required_header(self):
|
||||
input = """
|
||||
status,vrf
|
||||
Active,Test VRF
|
||||
"""
|
||||
with self.assertRaises(forms.ValidationError):
|
||||
self.field.clean(input)
|
||||
|
||||
def test_clean_default_to_field(self):
|
||||
input = """
|
||||
address,status,vrf.name
|
||||
192.0.2.1/32,Active,Test VRF
|
||||
"""
|
||||
output = (
|
||||
{'address': None, 'status': None, 'vrf': 'name'},
|
||||
[{'address': '192.0.2.1/32', 'status': 'Active', 'vrf': 'Test VRF'}]
|
||||
)
|
||||
self.assertEqual(self.field.clean(input), output)
|
||||
|
||||
def test_clean_pk_to_field(self):
|
||||
input = """
|
||||
address,status,vrf.pk
|
||||
192.0.2.1/32,Active,123
|
||||
"""
|
||||
output = (
|
||||
{'address': None, 'status': None, 'vrf': 'pk'},
|
||||
[{'address': '192.0.2.1/32', 'status': 'Active', 'vrf': '123'}]
|
||||
)
|
||||
self.assertEqual(self.field.clean(input), output)
|
||||
|
||||
def test_clean_custom_to_field(self):
|
||||
input = """
|
||||
address,status,vrf.rd
|
||||
192.0.2.1/32,Active,123:456
|
||||
"""
|
||||
output = (
|
||||
{'address': None, 'status': None, 'vrf': 'rd'},
|
||||
[{'address': '192.0.2.1/32', 'status': 'Active', 'vrf': '123:456'}]
|
||||
)
|
||||
self.assertEqual(self.field.clean(input), output)
|
||||
|
||||
def test_clean_invalid_to_field(self):
|
||||
input = """
|
||||
address,status,vrf.xxx
|
||||
192.0.2.1/32,Active,123:456
|
||||
"""
|
||||
with self.assertRaises(forms.ValidationError):
|
||||
self.field.clean(input)
|
||||
|
||||
def test_clean_to_field_on_non_object(self):
|
||||
input = """
|
||||
address,status.foo,vrf
|
||||
192.0.2.1/32,Bar,Test VRF
|
||||
"""
|
||||
with self.assertRaises(forms.ValidationError):
|
||||
self.field.clean(input)
|
||||
|
||||
|
||||
class ImportFormTest(TestCase):
|
||||
|
||||
def test_format_detection(self):
|
||||
|
Loading…
Reference in New Issue
Block a user