Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

custom none name #113

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CONTRIBUTING.rst
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ demo testing
to ensure the app behaves as expected, run the following::

$ cd test_app
$ python manage.py migrate
$ python manage.py runserver

then, visit ``http://localhost:8000/`` in your browser and confirm it produces a valid CSV.
Expand Down
13 changes: 10 additions & 3 deletions djqscsv/djqscsv.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
# the rest will be passed along to the csv writer
DJQSCSV_KWARGS = {
'field_header_map', 'field_serializer_map', 'use_verbose_names',
'field_order'}
'field_order', 'custom_none_name'}


class CSVException(Exception):
Expand Down Expand Up @@ -78,6 +78,7 @@ def _iter_csv(queryset, file_obj, **kwargs):
field_header_map = kwargs.get('field_header_map', {})
field_serializer_map = kwargs.get('field_serializer_map', {})
use_verbose_names = kwargs.get('use_verbose_names', True)
custom_none_name = kwargs.get('custom_none_name', None)
field_order = kwargs.get('field_order', None)

csv_kwargs = {'encoding': 'utf-8'}
Expand Down Expand Up @@ -152,7 +153,8 @@ def _iter_csv(queryset, file_obj, **kwargs):
yield writer.writerow(merged_header_map)

for record in values_qs:
record = _sanitize_record(field_serializer_map, record)
record = _sanitize_record(field_serializer_map, record,
custom_none_name)
yield writer.writerow(record)


Expand Down Expand Up @@ -186,7 +188,7 @@ def _validate_and_clean_filename(filename):
return filename


def _sanitize_record(field_serializer_map, record):
def _sanitize_record(field_serializer_map, record, custom_none_name):

def _serialize_value(value):
# provide default serializer for the case when
Expand All @@ -201,11 +203,16 @@ def _serialize_value(value):
if val is not None:
serializer = field_serializer_map.get(key, _serialize_value)
newval = serializer(val)
# If the user provided None
if newval is None:
newval = custom_none_name
# If the user provided serializer did not produce a string,
# coerce it to a string
if not isinstance(newval, six.text_type):
newval = six.text_type(newval)
obj[key] = newval
elif custom_none_name:
obj[key] = custom_none_name

return obj

Expand Down
32 changes: 27 additions & 5 deletions test_app/djqscsv_tests/tests/test_utilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,19 +47,41 @@ class SanitizeUnicodeRecordTests(TestCase):
def test_sanitize(self):
record = {'name': 'Tenar',
'nickname': u'\ufeffThe White Lady of Gont'}
sanitized = djqscsv._sanitize_record({}, record)
sanitized = djqscsv._sanitize_record({}, record, None)
self.assertEqual(sanitized,
{'name': 'Tenar',
'nickname': u'\ufeffThe White Lady of Gont'})

def test_sanitize_date(self):
record = {'name': 'Tenar',
'created': datetime.datetime(1, 1, 1)}
sanitized = djqscsv._sanitize_record({}, record)
sanitized = djqscsv._sanitize_record({}, record, None)
self.assertEqual(sanitized,
{'name': 'Tenar',
'created': '0001-01-01T00:00:00'})

def test_sanitize_with_custom_none_name(self):
"""
Ensure we retrieve custom none name
"""
record = {'name': 'Tenar',
'created': None}
custom_name_for_nones = "custom_name_for_nones"
sanitized = djqscsv._sanitize_record({}, record,
custom_name_for_nones)
self.assertEqual(sanitized,
{'name': 'Tenar',
'created': custom_name_for_nones})

record = {'name': 'Tenar',
'created': datetime.datetime(1, 1, 1)}
serializer = {'created': lambda x: None}
sanitized = djqscsv._sanitize_record(serializer, record,
custom_name_for_nones)
self.assertEqual(sanitized,
{'name': 'Tenar',
'created': custom_name_for_nones})

def test_sanitize_date_with_non_string_formatter(self):
"""
This test is only to make sure an edge case provides a sane
Expand All @@ -68,14 +90,14 @@ def test_sanitize_date_with_non_string_formatter(self):
"""
record = {'name': 'Tenar'}
serializer = {'name': lambda d: len(d)}
sanitized = djqscsv._sanitize_record(serializer, record)
sanitized = djqscsv._sanitize_record(serializer, record, None)
self.assertEqual(sanitized, {'name': '5'})

def test_sanitize_date_with_formatter(self):
record = {'name': 'Tenar',
'created': datetime.datetime(1973, 5, 13)}
serializer = {'created': lambda d: d.strftime('%Y-%m-%d')}
sanitized = djqscsv._sanitize_record(serializer, record)
sanitized = djqscsv._sanitize_record(serializer, record, None)
self.assertEqual(sanitized,
{'name': 'Tenar',
'created': '1973-05-13'})
Expand All @@ -84,7 +106,7 @@ def test_sanitize_date_with_bad_formatter(self):
record = {'name': 'Tenar',
'created': datetime.datetime(1973, 5, 13)}
with self.assertRaises(AttributeError):
djqscsv._sanitize_record(attrgetter('day'), record)
djqscsv._sanitize_record(attrgetter('day'), record, None)


class AppendDatestampTests(TestCase):
Expand Down