From a0ca977cab35123a741ecde2861b5a1623e49c20 Mon Sep 17 00:00:00 2001 From: Adrian Muntean Date: Thu, 14 Feb 2019 14:48:38 +0200 Subject: [PATCH 1/2] Set None in case the LocalizedIntegerField is null In case the LocalizedIntegerField is null in the DB then it must explicitly be set to None, otherwise it will yield TypeError: __str__ returned non-string --- README.rst | 2 +- localized_fields/widgets.py | 13 ++++++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/README.rst b/README.rst index 3d76f33..cb85a5f 100644 --- a/README.rst +++ b/README.rst @@ -279,7 +279,7 @@ Besides ``LocalizedField``, there's also: Allows storing integers in multiple languages. This works exactly like ``LocalizedField`` except that all values must be integers. Do note that values are stored as strings in your database because - the backing field type is ``hstore``, which only allows storing integers. The ``LocalizedIntegerField`` + the backing field type is ``hstore``, which only allows storing strings. The ``LocalizedIntegerField`` takes care of ensuring that all values are integers and converts the stored strings back to integers when retrieving them from the database. Do not expect to be able to do queries such as: diff --git a/localized_fields/widgets.py b/localized_fields/widgets.py index f48bf5a..2775a1f 100644 --- a/localized_fields/widgets.py +++ b/localized_fields/widgets.py @@ -6,7 +6,7 @@ from django.conf import settings from django import forms from django.contrib.admin import widgets -from .value import LocalizedValue +from .value import LocalizedValue, LocalizedIntegerValue class LocalizedFieldWidget(forms.MultiWidget): @@ -52,6 +52,7 @@ class LocalizedFieldWidget(forms.MultiWidget): return result def get_context(self, name, value, attrs): + value = self.remove_if_needed(value) context = super(forms.MultiWidget, self).get_context(name, value, attrs) if self.is_localized: for widget in self.widgets: @@ -98,6 +99,16 @@ class LocalizedFieldWidget(forms.MultiWidget): return attrs + @staticmethod + def remove_if_needed(value): + """If the field LocalizedIntegerField is null in the DB then it must + be set to None so it can be represented""" + if isinstance(value, LocalizedIntegerValue): + not_none_score = list(filter(lambda x: value[x] is not None, [i[0] for i in settings.LANGUAGES])) + return value if len(not_none_score) > 0 else None + else: + return value + class LocalizedCharFieldWidget(LocalizedFieldWidget): """Widget that has an input box for every language.""" From d8b872758c4686aed1146da9dfa82ae7836f1e5f Mon Sep 17 00:00:00 2001 From: Adrian Muntean Date: Wed, 20 Feb 2019 12:26:04 +0200 Subject: [PATCH 2/2] Return empty string in case of None --- localized_fields/value.py | 2 +- localized_fields/widgets.py | 13 +------------ 2 files changed, 2 insertions(+), 13 deletions(-) diff --git a/localized_fields/value.py b/localized_fields/value.py index 85c90cc..1c738d8 100644 --- a/localized_fields/value.py +++ b/localized_fields/value.py @@ -233,4 +233,4 @@ class LocalizedIntegerValue(LocalizedValue): """Returns string representation of value""" value = self.translate() - return str(value) if value is not None else None + return str(value) if value is not None else '' diff --git a/localized_fields/widgets.py b/localized_fields/widgets.py index 2775a1f..f48bf5a 100644 --- a/localized_fields/widgets.py +++ b/localized_fields/widgets.py @@ -6,7 +6,7 @@ from django.conf import settings from django import forms from django.contrib.admin import widgets -from .value import LocalizedValue, LocalizedIntegerValue +from .value import LocalizedValue class LocalizedFieldWidget(forms.MultiWidget): @@ -52,7 +52,6 @@ class LocalizedFieldWidget(forms.MultiWidget): return result def get_context(self, name, value, attrs): - value = self.remove_if_needed(value) context = super(forms.MultiWidget, self).get_context(name, value, attrs) if self.is_localized: for widget in self.widgets: @@ -99,16 +98,6 @@ class LocalizedFieldWidget(forms.MultiWidget): return attrs - @staticmethod - def remove_if_needed(value): - """If the field LocalizedIntegerField is null in the DB then it must - be set to None so it can be represented""" - if isinstance(value, LocalizedIntegerValue): - not_none_score = list(filter(lambda x: value[x] is not None, [i[0] for i in settings.LANGUAGES])) - return value if len(not_none_score) > 0 else None - else: - return value - class LocalizedCharFieldWidget(LocalizedFieldWidget): """Widget that has an input box for every language."""