Replaced smart_* by force_* calls whenever possible

The smart_* version should only be used when a lazy string should keep
its lazy status.
This commit is contained in:
Claude Paroz 2016-09-02 20:17:15 +02:00
parent b1d6b0a7b1
commit 2ced2f785d
23 changed files with 60 additions and 63 deletions

View File

@ -14,7 +14,7 @@ from django.contrib.admin.utils import (
from django.core.exceptions import ImproperlyConfigured, ValidationError from django.core.exceptions import ImproperlyConfigured, ValidationError
from django.db import models from django.db import models
from django.utils import timezone from django.utils import timezone
from django.utils.encoding import force_text, smart_text from django.utils.encoding import force_text
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
@ -207,7 +207,7 @@ class RelatedFieldListFilter(FieldListFilter):
} }
for pk_val, val in self.lookup_choices: for pk_val, val in self.lookup_choices:
yield { yield {
'selected': self.lookup_val == smart_text(pk_val), 'selected': self.lookup_val == force_text(pk_val),
'query_string': changelist.get_query_string({ 'query_string': changelist.get_query_string({
self.lookup_kwarg: pk_val, self.lookup_kwarg: pk_val,
}, [self.lookup_kwarg_isnull]), }, [self.lookup_kwarg_isnull]),
@ -292,7 +292,7 @@ class ChoicesFieldListFilter(FieldListFilter):
none_title = title none_title = title
continue continue
yield { yield {
'selected': smart_text(lookup) == self.lookup_val, 'selected': force_text(lookup) == self.lookup_val,
'query_string': changelist.get_query_string( 'query_string': changelist.get_query_string(
{self.lookup_kwarg: lookup}, [self.lookup_kwarg_isnull] {self.lookup_kwarg: lookup}, [self.lookup_kwarg_isnull]
), ),
@ -417,7 +417,7 @@ class AllValuesFieldListFilter(FieldListFilter):
if val is None: if val is None:
include_none = True include_none = True
continue continue
val = smart_text(val) val = force_text(val)
yield { yield {
'selected': self.lookup_val == val, 'selected': self.lookup_val == val,
'query_string': changelist.get_query_string({ 'query_string': changelist.get_query_string({

View File

@ -15,7 +15,7 @@ from django.forms.utils import flatatt
from django.template.defaultfilters import capfirst, linebreaksbr from django.template.defaultfilters import capfirst, linebreaksbr
from django.utils import six from django.utils import six
from django.utils.deprecation import RemovedInDjango20Warning from django.utils.deprecation import RemovedInDjango20Warning
from django.utils.encoding import force_text, smart_text from django.utils.encoding import force_text
from django.utils.html import conditional_escape, format_html from django.utils.html import conditional_escape, format_html
from django.utils.safestring import mark_safe from django.utils.safestring import mark_safe
from django.utils.translation import ugettext, ugettext_lazy as _ from django.utils.translation import ugettext, ugettext_lazy as _
@ -209,7 +209,7 @@ class AdminReadonlyField(object):
if hasattr(value, "__html__"): if hasattr(value, "__html__"):
result_repr = value result_repr = value
else: else:
result_repr = smart_text(value) result_repr = force_text(value)
if getattr(attr, "allow_tags", False): if getattr(attr, "allow_tags", False):
warnings.warn( warnings.warn(
"Deprecated allow_tags attribute used on %s. " "Deprecated allow_tags attribute used on %s. "

View File

@ -8,7 +8,7 @@ from django.contrib.contenttypes.models import ContentType
from django.db import models from django.db import models
from django.urls import NoReverseMatch, reverse from django.urls import NoReverseMatch, reverse
from django.utils import timezone from django.utils import timezone
from django.utils.encoding import python_2_unicode_compatible, smart_text from django.utils.encoding import force_text, python_2_unicode_compatible
from django.utils.text import get_text_list from django.utils.text import get_text_list
from django.utils.translation import ugettext, ugettext_lazy as _ from django.utils.translation import ugettext, ugettext_lazy as _
@ -26,7 +26,7 @@ class LogEntryManager(models.Manager):
self.model.objects.create( self.model.objects.create(
user_id=user_id, user_id=user_id,
content_type_id=content_type_id, content_type_id=content_type_id,
object_id=smart_text(object_id), object_id=force_text(object_id),
object_repr=object_repr[:200], object_repr=object_repr[:200],
action_flag=action_flag, action_flag=action_flag,
change_message=change_message, change_message=change_message,
@ -67,7 +67,7 @@ class LogEntry(models.Model):
ordering = ('-action_time',) ordering = ('-action_time',)
def __repr__(self): def __repr__(self):
return smart_text(self.action_time) return force_text(self.action_time)
def __str__(self): def __str__(self):
if self.is_addition(): if self.is_addition():

View File

@ -435,7 +435,7 @@ def display_for_value(value, empty_value_display, boolean=False):
elif isinstance(value, (list, tuple)): elif isinstance(value, (list, tuple)):
return ', '.join(force_text(v) for v in value) return ', '.join(force_text(v) for v in value)
else: else:
return smart_text(value) return force_text(value)
class NotRelationField(Exception): class NotRelationField(Exception):

View File

@ -13,7 +13,7 @@ from django.db.models.fields.related import (
lazy_related_operation, lazy_related_operation,
) )
from django.db.models.query_utils import PathInfo from django.db.models.query_utils import PathInfo
from django.utils.encoding import python_2_unicode_compatible, smart_text from django.utils.encoding import force_text, python_2_unicode_compatible
from django.utils.functional import cached_property from django.utils.functional import cached_property
@ -402,7 +402,7 @@ class GenericRelation(ForeignObject):
def value_to_string(self, obj): def value_to_string(self, obj):
qs = getattr(obj, self.name).all() qs = getattr(obj, self.name).all()
return smart_text([instance._get_pk_val() for instance in qs]) return force_text([instance._get_pk_val() for instance in qs])
def contribute_to_class(self, cls, name, **kwargs): def contribute_to_class(self, cls, name, **kwargs):
kwargs['private_only'] = True kwargs['private_only'] = True

View File

@ -9,7 +9,7 @@ from django.contrib.staticfiles.storage import staticfiles_storage
from django.core.files.storage import FileSystemStorage from django.core.files.storage import FileSystemStorage
from django.core.management.base import BaseCommand, CommandError from django.core.management.base import BaseCommand, CommandError
from django.core.management.color import no_style from django.core.management.color import no_style
from django.utils.encoding import smart_text from django.utils.encoding import force_text
from django.utils.functional import cached_property from django.utils.functional import cached_property
from django.utils.six.moves import input from django.utils.six.moves import input
@ -237,10 +237,9 @@ class Command(BaseCommand):
for f in files: for f in files:
fpath = os.path.join(path, f) fpath = os.path.join(path, f)
if self.dry_run: if self.dry_run:
self.log("Pretending to delete '%s'" % self.log("Pretending to delete '%s'" % force_text(fpath), level=1)
smart_text(fpath), level=1)
else: else:
self.log("Deleting '%s'" % smart_text(fpath), level=1) self.log("Deleting '%s'" % force_text(fpath), level=1)
try: try:
full_path = self.storage.path(fpath) full_path = self.storage.path(fpath)
except NotImplementedError: except NotImplementedError:

View File

@ -8,7 +8,7 @@ from django.core.exceptions import ImproperlyConfigured, ObjectDoesNotExist
from django.http import Http404, HttpResponse from django.http import Http404, HttpResponse
from django.template import TemplateDoesNotExist, loader from django.template import TemplateDoesNotExist, loader
from django.utils import feedgenerator, six from django.utils import feedgenerator, six
from django.utils.encoding import force_text, iri_to_uri, smart_text from django.utils.encoding import force_text, iri_to_uri
from django.utils.html import escape from django.utils.html import escape
from django.utils.http import http_date from django.utils.http import http_date
from django.utils.timezone import get_default_timezone, is_naive, make_aware from django.utils.timezone import get_default_timezone, is_naive, make_aware
@ -68,9 +68,9 @@ class Feed(object):
enc_url = self._get_dynamic_attr('item_enclosure_url', item) enc_url = self._get_dynamic_attr('item_enclosure_url', item)
if enc_url: if enc_url:
enc = feedgenerator.Enclosure( enc = feedgenerator.Enclosure(
url=smart_text(enc_url), url=force_text(enc_url),
length=smart_text(self._get_dynamic_attr('item_enclosure_length', item)), length=force_text(self._get_dynamic_attr('item_enclosure_length', item)),
mime_type=smart_text(self._get_dynamic_attr('item_enclosure_mime_type', item)), mime_type=force_text(self._get_dynamic_attr('item_enclosure_mime_type', item)),
) )
return [enc] return [enc]
return [] return []

View File

@ -6,7 +6,7 @@ from io import BytesIO, StringIO, UnsupportedOperation
from django.core.files.utils import FileProxyMixin from django.core.files.utils import FileProxyMixin
from django.utils import six from django.utils import six
from django.utils.encoding import ( from django.utils.encoding import (
force_bytes, force_str, python_2_unicode_compatible, smart_text, force_bytes, force_str, force_text, python_2_unicode_compatible,
) )
@ -23,7 +23,7 @@ class File(FileProxyMixin):
self.mode = file.mode self.mode = file.mode
def __str__(self): def __str__(self):
return smart_text(self.name or '') return force_text(self.name or '')
def __repr__(self): def __repr__(self):
return force_str("<%s: %s>" % (self.__class__.__name__, self or "None")) return force_str("<%s: %s>" % (self.__class__.__name__, self or "None"))

View File

@ -13,7 +13,7 @@ from django.apps import apps
from django.conf import settings from django.conf import settings
from django.core.serializers import base from django.core.serializers import base
from django.db import DEFAULT_DB_ALIAS, models from django.db import DEFAULT_DB_ALIAS, models
from django.utils.encoding import smart_text from django.utils.encoding import force_text
from django.utils.xmlutils import ( from django.utils.xmlutils import (
SimplerXMLGenerator, UnserializableContentError, SimplerXMLGenerator, UnserializableContentError,
) )
@ -52,11 +52,11 @@ class Serializer(base.Serializer):
raise base.SerializationError("Non-model object (%s) encountered during serialization" % type(obj)) raise base.SerializationError("Non-model object (%s) encountered during serialization" % type(obj))
self.indent(1) self.indent(1)
attrs = OrderedDict([("model", smart_text(obj._meta))]) attrs = OrderedDict([("model", force_text(obj._meta))])
if not self.use_natural_primary_keys or not hasattr(obj, 'natural_key'): if not self.use_natural_primary_keys or not hasattr(obj, 'natural_key'):
obj_pk = obj._get_pk_val() obj_pk = obj._get_pk_val()
if obj_pk is not None: if obj_pk is not None:
attrs['pk'] = smart_text(obj_pk) attrs['pk'] = force_text(obj_pk)
self.xml.startElement("object", attrs) self.xml.startElement("object", attrs)
@ -105,10 +105,10 @@ class Serializer(base.Serializer):
# Iterable natural keys are rolled out as subelements # Iterable natural keys are rolled out as subelements
for key_value in related: for key_value in related:
self.xml.startElement("natural", {}) self.xml.startElement("natural", {})
self.xml.characters(smart_text(key_value)) self.xml.characters(force_text(key_value))
self.xml.endElement("natural") self.xml.endElement("natural")
else: else:
self.xml.characters(smart_text(related_att)) self.xml.characters(force_text(related_att))
else: else:
self.xml.addQuickElement("None") self.xml.addQuickElement("None")
self.xml.endElement("field") self.xml.endElement("field")
@ -129,13 +129,13 @@ class Serializer(base.Serializer):
self.xml.startElement("object", {}) self.xml.startElement("object", {})
for key_value in natural: for key_value in natural:
self.xml.startElement("natural", {}) self.xml.startElement("natural", {})
self.xml.characters(smart_text(key_value)) self.xml.characters(force_text(key_value))
self.xml.endElement("natural") self.xml.endElement("natural")
self.xml.endElement("object") self.xml.endElement("object")
else: else:
def handle_m2m(value): def handle_m2m(value):
self.xml.addQuickElement("object", attrs={ self.xml.addQuickElement("object", attrs={
'pk': smart_text(value._get_pk_val()) 'pk': force_text(value._get_pk_val())
}) })
for relobj in getattr(obj, field.name).iterator(): for relobj in getattr(obj, field.name).iterator():
handle_m2m(relobj) handle_m2m(relobj)
@ -150,7 +150,7 @@ class Serializer(base.Serializer):
self.xml.startElement("field", OrderedDict([ self.xml.startElement("field", OrderedDict([
("name", field.name), ("name", field.name),
("rel", field.remote_field.__class__.__name__), ("rel", field.remote_field.__class__.__name__),
("to", smart_text(field.remote_field.model._meta)), ("to", force_text(field.remote_field.model._meta)),
])) ]))

View File

@ -15,7 +15,7 @@ from django.db.models.options import DEFAULT_NAMES, normalize_together
from django.db.models.utils import make_model_tuple from django.db.models.utils import make_model_tuple
from django.utils import six from django.utils import six
from django.utils.deprecation import RemovedInDjango20Warning from django.utils.deprecation import RemovedInDjango20Warning
from django.utils.encoding import force_text, smart_text from django.utils.encoding import force_text
from django.utils.functional import cached_property from django.utils.functional import cached_property
from django.utils.module_loading import import_string from django.utils.module_loading import import_string
from django.utils.version import get_docs_version from django.utils.version import get_docs_version
@ -494,7 +494,7 @@ class ModelState(object):
@classmethod @classmethod
def force_text_recursive(cls, value): def force_text_recursive(cls, value):
if isinstance(value, six.string_types): if isinstance(value, six.string_types):
return smart_text(value) return force_text(value)
elif isinstance(value, list): elif isinstance(value, list):
return [cls.force_text_recursive(x) for x in value] return [cls.force_text_recursive(x) for x in value]
elif isinstance(value, tuple): elif isinstance(value, tuple):

View File

@ -817,7 +817,7 @@ class Field(RegisterLookupMixin):
Returns a string value of this field from the passed obj. Returns a string value of this field from the passed obj.
This is used by the serialization framework. This is used by the serialization framework.
""" """
return smart_text(self.value_from_object(obj)) return force_text(self.value_from_object(obj))
def _get_flatchoices(self): def _get_flatchoices(self):
"""Flattened version of choices tuple.""" """Flattened version of choices tuple."""
@ -1075,7 +1075,7 @@ class CharField(Field):
def to_python(self, value): def to_python(self, value):
if isinstance(value, six.string_types) or value is None: if isinstance(value, six.string_types) or value is None:
return value return value
return smart_text(value) return force_text(value)
def get_prep_value(self, value): def get_prep_value(self, value):
value = super(CharField, self).get_prep_value(value) value = super(CharField, self).get_prep_value(value)
@ -2129,7 +2129,7 @@ class TextField(Field):
def to_python(self, value): def to_python(self, value):
if isinstance(value, six.string_types) or value is None: if isinstance(value, six.string_types) or value is None:
return value return value
return smart_text(value) return force_text(value)
def get_prep_value(self, value): def get_prep_value(self, value):
value = super(TextField, self).get_prep_value(value) value = super(TextField, self).get_prep_value(value)

View File

@ -15,7 +15,7 @@ import warnings
from django.core import exceptions from django.core import exceptions
from django.utils.deprecation import RemovedInDjango20Warning from django.utils.deprecation import RemovedInDjango20Warning
from django.utils.encoding import smart_text from django.utils.encoding import force_text
from django.utils.functional import cached_property from django.utils.functional import cached_property
from . import BLANK_CHOICE_DASH from . import BLANK_CHOICE_DASH
@ -136,7 +136,7 @@ class ForeignObjectRel(object):
initially for utilization by RelatedFieldListFilter. initially for utilization by RelatedFieldListFilter.
""" """
return (blank_choice if include_blank else []) + [ return (blank_choice if include_blank else []) + [
(x._get_pk_val(), smart_text(x)) for x in self.related_model._default_manager.all() (x._get_pk_val(), force_text(x)) for x in self.related_model._default_manager.all()
] ]
def is_hidden(self): def is_hidden(self):

View File

@ -5,9 +5,7 @@ import datetime
from django.forms.utils import flatatt, pretty_name from django.forms.utils import flatatt, pretty_name
from django.forms.widgets import Textarea, TextInput from django.forms.widgets import Textarea, TextInput
from django.utils import six from django.utils import six
from django.utils.encoding import ( from django.utils.encoding import force_text, python_2_unicode_compatible
force_text, python_2_unicode_compatible, smart_text,
)
from django.utils.functional import cached_property from django.utils.functional import cached_property
from django.utils.html import conditional_escape, format_html, html_safe from django.utils.html import conditional_escape, format_html, html_safe
from django.utils.safestring import mark_safe from django.utils.safestring import mark_safe
@ -196,8 +194,8 @@ class BoundField(object):
associated Form has specified auto_id. Returns an empty string otherwise. associated Form has specified auto_id. Returns an empty string otherwise.
""" """
auto_id = self.form.auto_id auto_id = self.form.auto_id
if auto_id and '%s' in smart_text(auto_id): if auto_id and '%s' in force_text(auto_id):
return smart_text(auto_id) % self.html_name return force_text(auto_id) % self.html_name
elif auto_id: elif auto_id:
return self.html_name return self.html_name
return '' return ''

View File

@ -30,7 +30,7 @@ from django.forms.widgets import (
from django.utils import formats, six from django.utils import formats, six
from django.utils.dateparse import parse_duration from django.utils.dateparse import parse_duration
from django.utils.duration import duration_string from django.utils.duration import duration_string
from django.utils.encoding import force_str, force_text, smart_text from django.utils.encoding import force_str, force_text
from django.utils.ipv6 import clean_ipv6_address from django.utils.ipv6 import clean_ipv6_address
from django.utils.six.moves.urllib.parse import urlsplit, urlunsplit from django.utils.six.moves.urllib.parse import urlsplit, urlunsplit
from django.utils.translation import ugettext_lazy as _, ungettext_lazy from django.utils.translation import ugettext_lazy as _, ungettext_lazy
@ -349,7 +349,7 @@ class DecimalField(IntegerField):
return None return None
if self.localize: if self.localize:
value = formats.sanitize_separators(value) value = formats.sanitize_separators(value)
value = smart_text(value).strip() value = force_text(value).strip()
try: try:
value = Decimal(value) value = Decimal(value)
except DecimalException: except DecimalException:
@ -799,7 +799,7 @@ class ChoiceField(Field):
"Returns a Unicode object." "Returns a Unicode object."
if value in self.empty_values: if value in self.empty_values:
return '' return ''
return smart_text(value) return force_text(value)
def validate(self, value): def validate(self, value):
""" """
@ -868,7 +868,7 @@ class MultipleChoiceField(ChoiceField):
return [] return []
elif not isinstance(value, (list, tuple)): elif not isinstance(value, (list, tuple)):
raise ValidationError(self.error_messages['invalid_list'], code='invalid_list') raise ValidationError(self.error_messages['invalid_list'], code='invalid_list')
return [smart_text(val) for val in value] return [force_text(val) for val in value]
def validate(self, value): def validate(self, value):
""" """

View File

@ -19,7 +19,7 @@ from django.forms.widgets import (
HiddenInput, MultipleHiddenInput, SelectMultiple, HiddenInput, MultipleHiddenInput, SelectMultiple,
) )
from django.utils import six from django.utils import six
from django.utils.encoding import force_text, smart_text from django.utils.encoding import force_text
from django.utils.text import capfirst, get_text_list from django.utils.text import capfirst, get_text_list
from django.utils.translation import ugettext, ugettext_lazy as _ from django.utils.translation import ugettext, ugettext_lazy as _
@ -1186,7 +1186,7 @@ class ModelChoiceField(ChoiceField):
generate the labels for the choices presented by this object. Subclasses generate the labels for the choices presented by this object. Subclasses
can override this method to customize the display of the choices. can override this method to customize the display of the choices.
""" """
return smart_text(obj) return force_text(obj)
def _get_choices(self): def _get_choices(self):
# If self._choices is set, then somebody must have manually set # If self._choices is set, then somebody must have manually set

View File

@ -521,7 +521,7 @@ class QueryDict(MultiValueDict):
# It's neither necessary nor appropriate to use # It's neither necessary nor appropriate to use
# django.utils.encoding.smart_text for parsing URLs and form inputs. Thus, # django.utils.encoding.force_text for parsing URLs and form inputs. Thus,
# this slightly more restricted function, used by QueryDict. # this slightly more restricted function, used by QueryDict.
def bytes_to_text(s, encoding): def bytes_to_text(s, encoding):
""" """

View File

@ -13,7 +13,7 @@ import itertools
from django.conf import settings from django.conf import settings
from django.middleware.csrf import get_token from django.middleware.csrf import get_token
from django.utils.encoding import smart_text from django.utils.encoding import force_text
from django.utils.functional import SimpleLazyObject, lazy from django.utils.functional import SimpleLazyObject, lazy
@ -30,7 +30,7 @@ def csrf(request):
# instead of returning an empty dict. # instead of returning an empty dict.
return 'NOTPROVIDED' return 'NOTPROVIDED'
else: else:
return smart_text(token) return force_text(token)
return {'csrf_token': SimpleLazyObject(_get_val)} return {'csrf_token': SimpleLazyObject(_get_val)}

View File

@ -10,7 +10,7 @@ from itertools import cycle as itertools_cycle, groupby
from django.conf import settings from django.conf import settings
from django.utils import six, timezone from django.utils import six, timezone
from django.utils.encoding import force_text, smart_text from django.utils.encoding import force_text
from django.utils.html import conditional_escape, format_html from django.utils.html import conditional_escape, format_html
from django.utils.lorem_ipsum import paragraphs, words from django.utils.lorem_ipsum import paragraphs, words
from django.utils.safestring import mark_safe from django.utils.safestring import mark_safe
@ -440,7 +440,7 @@ class URLNode(Node):
from django.urls import reverse, NoReverseMatch from django.urls import reverse, NoReverseMatch
args = [arg.resolve(context) for arg in self.args] args = [arg.resolve(context) for arg in self.args]
kwargs = { kwargs = {
smart_text(k, 'ascii'): v.resolve(context) force_text(k, 'ascii'): v.resolve(context)
for k, v in self.kwargs.items() for k, v in self.kwargs.items()
} }
view_name = self.view_name.resolve(context) view_name = self.view_name.resolve(context)

View File

@ -11,7 +11,7 @@ from django.template.defaultfilters import force_escape, pprint
from django.urls import Resolver404, resolve from django.urls import Resolver404, resolve
from django.utils import lru_cache, six, timezone from django.utils import lru_cache, six, timezone
from django.utils.datastructures import MultiValueDict from django.utils.datastructures import MultiValueDict
from django.utils.encoding import force_bytes, smart_text from django.utils.encoding import force_bytes, force_text
from django.utils.module_loading import import_string from django.utils.module_loading import import_string
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
@ -280,7 +280,7 @@ class ExceptionReporter(object):
end = getattr(self.exc_value, 'end', None) end = getattr(self.exc_value, 'end', None)
if start is not None and end is not None: if start is not None and end is not None:
unicode_str = self.exc_value.args[1] unicode_str = self.exc_value.args[1]
unicode_hint = smart_text( unicode_hint = force_text(
unicode_str[max(start - 5, 0):min(end + 5, len(unicode_str))], unicode_str[max(start - 5, 0):min(end + 5, len(unicode_str))],
'ascii', errors='replace' 'ascii', errors='replace'
) )
@ -305,7 +305,7 @@ class ExceptionReporter(object):
if self.exc_type: if self.exc_type:
c['exception_type'] = self.exc_type.__name__ c['exception_type'] = self.exc_type.__name__
if self.exc_value: if self.exc_value:
c['exception_value'] = smart_text(self.exc_value, errors='replace') c['exception_value'] = force_text(self.exc_value, errors='replace')
if frames: if frames:
c['lastframe'] = frames[-1] c['lastframe'] = frames[-1]
return c return c

View File

@ -12,7 +12,7 @@ from django.urls import translate_url
from django.utils import six from django.utils import six
from django.utils._os import upath from django.utils._os import upath
from django.utils.deprecation import RemovedInDjango20Warning from django.utils.deprecation import RemovedInDjango20Warning
from django.utils.encoding import smart_text from django.utils.encoding import force_text
from django.utils.formats import get_format from django.utils.formats import get_format
from django.utils.http import is_safe_url, urlunquote from django.utils.http import is_safe_url, urlunquote
from django.utils.translation import ( from django.utils.translation import (
@ -81,9 +81,9 @@ def get_formats():
formats = {} formats = {}
for k, v in result.items(): for k, v in result.items():
if isinstance(v, (six.string_types, int)): if isinstance(v, (six.string_types, int)):
formats[k] = smart_text(v) formats[k] = force_text(v)
elif isinstance(v, (tuple, list)): elif isinstance(v, (tuple, list)):
formats[k] = [smart_text(value) for value in v] formats[k] = [force_text(value) for value in v]
return formats return formats

View File

@ -369,7 +369,7 @@ to you, the developer, to handle the fact that you will receive bytestrings if
you configure your table(s) to use ``utf8_bin`` collation. Django itself should you configure your table(s) to use ``utf8_bin`` collation. Django itself should
mostly work smoothly with such columns (except for the ``contrib.sessions`` mostly work smoothly with such columns (except for the ``contrib.sessions``
``Session`` and ``contrib.admin`` ``LogEntry`` tables described below), but ``Session`` and ``contrib.admin`` ``LogEntry`` tables described below), but
your code must be prepared to call ``django.utils.encoding.smart_text()`` at your code must be prepared to call ``django.utils.encoding.force_text()`` at
times if it really wants to work with consistent data -- Django will not do times if it really wants to work with consistent data -- Django will not do
this for you (the database backend layer and the model population layer are this for you (the database backend layer and the model population layer are
separated internally so the database layer doesn't know it needs to make this separated internally so the database layer doesn't know it needs to make this

View File

@ -163,7 +163,7 @@ for converting back and forth between Unicode and bytestrings.
slightly different semantics from Python's builtin ``str()`` function, slightly different semantics from Python's builtin ``str()`` function,
but the difference is needed in a few places within Django's internals. but the difference is needed in a few places within Django's internals.
Normally, you'll only need to use ``smart_text()``. Call it as early as Normally, you'll only need to use ``force_text()``. Call it as early as
possible on any input data that might be either Unicode or a bytestring, and possible on any input data that might be either Unicode or a bytestring, and
from then on, you can treat the result as always being Unicode. from then on, you can treat the result as always being Unicode.

View File

@ -8,7 +8,7 @@ import os
from django.core.files.uploadedfile import UploadedFile from django.core.files.uploadedfile import UploadedFile
from django.http import HttpResponse, HttpResponseServerError from django.http import HttpResponse, HttpResponseServerError
from django.utils import six from django.utils import six
from django.utils.encoding import force_bytes, smart_str from django.utils.encoding import force_bytes, force_str
from .models import FileModel from .models import FileModel
from .tests import UNICODE_FILENAME, UPLOAD_TO from .tests import UNICODE_FILENAME, UPLOAD_TO
@ -158,7 +158,7 @@ def file_upload_content_type_extra(request):
params = {} params = {}
for file_name, uploadedfile in request.FILES.items(): for file_name, uploadedfile in request.FILES.items():
params[file_name] = { params[file_name] = {
k: smart_str(v) for k, v in uploadedfile.content_type_extra.items() k: force_str(v) for k, v in uploadedfile.content_type_extra.items()
} }
return HttpResponse(json.dumps(params)) return HttpResponse(json.dumps(params))