Skip to content

Commit

Permalink
Add check for type to widget render
Browse files Browse the repository at this point in the history
  • Loading branch information
matthewhegarty committed Feb 13, 2024
1 parent b8b98ca commit 8b98b68
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 6 deletions.
1 change: 1 addition & 0 deletions docs/changelog.rst
Expand Up @@ -20,6 +20,7 @@ Changelog
(#1735)
- Updated Admin integration documentation to clarify how to save custom form values (#1746)
- Updated test coverage to include error row when ``collect_failed_rows`` is ``True`` (#1753)
- Add check for type to :meth:`~import_export.widgets.Widget.render` (#)

4.0.0-beta.2 (2023-12-09)
-------------------------
Expand Down
15 changes: 9 additions & 6 deletions import_export/widgets.py
@@ -1,6 +1,7 @@
import json
import logging
from datetime import date, datetime, time
import numbers
from datetime import date, datetime, time, timedelta
from decimal import Decimal
from warnings import warn

Expand Down Expand Up @@ -86,6 +87,8 @@ def is_empty(self, value):

def render(self, value, obj=None):
self._obj_deprecation_warning(obj)
if not isinstance(value, numbers.Number):
return ""
if self.coerce_to_string:
return "" if value is None else number_format(value)
return value
Expand Down Expand Up @@ -204,7 +207,7 @@ def render(self, value, obj=None):
self._obj_deprecation_warning(obj)
if self.coerce_to_string is False:
return value
if value in self.NULL_VALUES:
if value in self.NULL_VALUES or not type(value) is bool:
return ""
return self.TRUE_VALUES[0] if value else self.FALSE_VALUES[0]

Expand Down Expand Up @@ -248,7 +251,7 @@ def render(self, value, obj=None):
self._obj_deprecation_warning(obj)
if self.coerce_to_string is False:
return value
if not value:
if not value or not type(value) is date:
return ""
return format_datetime(value, self.formats[0])

Expand Down Expand Up @@ -298,7 +301,7 @@ def render(self, value, obj=None):
self._obj_deprecation_warning(obj)
if self.coerce_to_string is False:
return value
if not value:
if not value or not type(value) is datetime:
return ""
if settings.USE_TZ:
value = timezone.localtime(value)
Expand Down Expand Up @@ -344,7 +347,7 @@ def render(self, value, obj=None):
self._obj_deprecation_warning(obj)
if self.coerce_to_string is False:
return value
if not value:
if not value or not type(value) is time:
return ""
return value.strftime(self.formats[0])

Expand Down Expand Up @@ -372,7 +375,7 @@ def render(self, value, obj=None):
self._obj_deprecation_warning(obj)
if self.coerce_to_string is False:
return value
if value is None:
if value is None or not type(value) is timedelta:
return ""
return str(value)

Expand Down
27 changes: 27 additions & 0 deletions tests/core/tests/test_widgets.py
Expand Up @@ -93,6 +93,9 @@ def test_render_coerce_to_string_is_False(self):
self.assertFalse(self.widget.render(False))
self.assertIsNone(self.widget.render(None))

def test_render_invalid_type(self):
self.assertEqual(self.widget.render("a"), "")


class FormatDatetimeTest(TestCase):
date = date(10, 8, 2)
Expand Down Expand Up @@ -127,6 +130,9 @@ def test_render(self):
def test_render_none(self):
self.assertEqual(self.widget.render(None), "")

def test_render_invalid_type(self):
self.assertEqual(self.widget.render(int(1)), "")

def test_render_coerce_to_string_is_False(self):
self.widget = widgets.DateWidget(coerce_to_string=False)
self.assertEqual(self.date, self.widget.render(self.date))
Expand Down Expand Up @@ -178,6 +184,9 @@ def test_render(self):
def test_render_none(self):
self.assertEqual(self.widget.render(None), "")

def test_render_invalid_type(self):
self.assertEqual(self.widget.render(int(1)), "")

def test_render_coerce_to_string_is_False(self):
self.widget = widgets.DateTimeWidget(coerce_to_string=False)
self.assertEqual(self.datetime, self.widget.render(self.datetime))
Expand Down Expand Up @@ -279,6 +288,9 @@ def test_render(self):
def test_render_none(self):
self.assertEqual(self.widget.render(None), "")

def test_render_invalid_type(self):
self.assertEqual(self.widget.render(int(1)), "")

def test_render_coerce_to_string_is_False(self):
self.widget = widgets.TimeWidget(coerce_to_string=False)
self.assertEqual(self.time, self.widget.render(self.time))
Expand Down Expand Up @@ -324,6 +336,9 @@ def test_render_coerce_to_string_is_False(self):
self.widget = widgets.DurationWidget(coerce_to_string=False)
self.assertEqual(self.duration, self.widget.render(self.duration))

def test_render_invalid_type(self):
self.assertEqual(self.widget.render(int(1)), "")

def test_clean(self):
self.assertEqual(self.widget.clean("1:57:00"), self.duration)

Expand Down Expand Up @@ -365,6 +380,9 @@ def test_render(self):
def test_render_None_coerce_to_string_False(self):
self.assertEqual("", self.widget.render(None))

def test_render_invalid_type(self):
self.assertEqual(self.widget.render("a"), "")

@skipUnless(
django.VERSION[0] < 4, f"skipping django {django.VERSION} version specific test"
)
Expand Down Expand Up @@ -396,6 +414,9 @@ def test_clean(self):
def test_render(self):
self.assertEqual(self.widget.render(self.value), "11.111")

def test_render_invalid_type(self):
self.assertEqual(self.widget.render("a"), "")

def test_clean_string_zero(self):
self.assertEqual(self.widget.clean("0"), 0.0)
self.assertEqual(self.widget.clean("0.0"), 0.0)
Expand Down Expand Up @@ -437,6 +458,9 @@ def test_render_coerce_to_string_is_False(self):
def test_render(self):
self.assertEqual(self.widget.render(self.value), "11.111")

def test_render_invalid_type(self):
self.assertEqual(self.widget.render("1"), "")

def test_clean_string_zero(self):
self.assertEqual(self.widget.clean("0"), Decimal("0"))
self.assertEqual(self.widget.clean("0.0"), Decimal("0"))
Expand Down Expand Up @@ -484,6 +508,9 @@ def test_clean_empty_string(self):
self.assertEqual(self.widget.clean(" "), None)
self.assertEqual(self.widget.clean("\n\t\r"), None)

def test_render_invalid_type(self):
self.assertEqual(self.widget.render("a"), "")

@skipUnless(
django.VERSION[0] < 4, f"skipping django {django.VERSION} version specific test"
)
Expand Down

0 comments on commit 8b98b68

Please sign in to comment.