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

NumberWidget.render() returns None as string #1650

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions docs/api_widgets.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ Widgets
.. autoclass:: import_export.widgets.Widget
:members:

.. autoclass:: import_export.widgets.NumberWidget
:members:

.. autoclass:: import_export.widgets.IntegerWidget
:members:

Expand Down
2 changes: 2 additions & 0 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ Changelog

- Updated Spanish translations (#1639)
- Added documentation and tests for retrieving instance information after import (#1643)
- :meth:`~import_export.widgets.NumberWidget.render` returns ``None`` as empty string
if ``coerce_to_string`` is True (#1650)


3.3.1 (2023-09-14)
Expand Down
18 changes: 11 additions & 7 deletions import_export/widgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,10 @@ def render(self, value, obj=None):

class NumberWidget(Widget):
"""
Takes optional ``coerce_to_string`` parameter, set to ``True`` the
:meth:`~import_export.widgets.Widget.render` method will return a string
else it will return a value.
Widget for converting numeric fields.

:param coerce_to_string: If True, render will return a string representation
of the value (None is returned as ""), otherwise the value is returned.
"""

def __init__(self, coerce_to_string=False):
Expand All @@ -71,12 +72,14 @@ def is_empty(self, value):
return value is None or value == ""

def render(self, value, obj=None):
return number_format(value) if self.coerce_to_string else value
if self.coerce_to_string:
return "" if value is None else number_format(value)
return value


class FloatWidget(NumberWidget):
"""
Widget for converting floats fields.
Widget for converting float fields.
"""

def clean(self, value, row=None, **kwargs):
Expand Down Expand Up @@ -112,12 +115,13 @@ class CharWidget(Widget):
Widget for converting text fields.

:param coerce_to_string: If True, the value returned by clean() is cast to a
string.
string.
:param allow_blank: If True, and if coerce_to_string is True, then clean() will
return null values as empty strings, otherwise as null.
return null values as empty strings, otherwise as null.
"""

def __init__(self, coerce_to_string=False, allow_blank=False):
""" """
self.coerce_to_string = coerce_to_string
self.allow_blank = allow_blank

Expand Down
12 changes: 9 additions & 3 deletions tests/core/tests/test_widgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -300,22 +300,28 @@ def test_is_empty_value_is_zero(self):
self.assertFalse(self.widget.is_empty(0))

def test_render(self):
self.assertEqual(self.widget.render(self.value), self.value)
self.assertEqual(self.value, self.widget.render(self.value))

def test_render_None_coerce_to_string_False(self):
self.assertIsNone(self.widget.render(None))

@skipUnless(
django.VERSION[0] < 4, f"skipping django {django.VERSION} version specific test"
)
@override_settings(LANGUAGE_CODE="fr-fr", USE_L10N=True)
def test_locale_render_coerce_to_string_lt4(self):
self.assertEqual(self.widget_coerce_to_string.render(self.value), "11,111")
self.assertEqual("11,111", self.widget_coerce_to_string.render(self.value))

@skipUnless(
django.VERSION[0] >= 4,
f"skipping django {django.VERSION} version specific test",
)
@override_settings(LANGUAGE_CODE="fr-fr")
def test_locale_render_coerce_to_string_gte4(self):
self.assertEqual(self.widget_coerce_to_string.render(self.value), "11,111")
self.assertEqual("11,111", self.widget_coerce_to_string.render(self.value))

def test_coerce_to_string_value_is_None(self):
self.assertEqual("", self.widget_coerce_to_string.render(None))


class FloatWidgetTest(TestCase):
Expand Down