parent
888c1e9bfe
commit
d1bab24e01
|
@ -283,10 +283,7 @@ def lookup_field(name, obj, model_admin=None):
|
||||||
if callable(name):
|
if callable(name):
|
||||||
attr = name
|
attr = name
|
||||||
value = attr(obj)
|
value = attr(obj)
|
||||||
elif (model_admin is not None and
|
elif model_admin is not None and hasattr(model_admin, name) and name != '__str__':
|
||||||
hasattr(model_admin, name) and
|
|
||||||
not name == '__str__' and
|
|
||||||
not name == '__unicode__'):
|
|
||||||
attr = getattr(model_admin, name)
|
attr = getattr(model_admin, name)
|
||||||
value = attr(obj)
|
value = attr(obj)
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -84,10 +84,8 @@ def create_permissions(app_config, verbosity=2, interactive=True, using=DEFAULT_
|
||||||
|
|
||||||
def get_system_username():
|
def get_system_username():
|
||||||
"""
|
"""
|
||||||
Try to determine the current system user's username.
|
Return the current system user's username, or an empty string if the
|
||||||
|
username could not be determined.
|
||||||
:returns: The username as a unicode string, or an empty string if the
|
|
||||||
username could not be determined.
|
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
result = getpass.getuser()
|
result = getpass.getuser()
|
||||||
|
|
|
@ -11,8 +11,8 @@ class GeoFeedMixin:
|
||||||
def georss_coords(self, coords):
|
def georss_coords(self, coords):
|
||||||
"""
|
"""
|
||||||
In GeoRSS coordinate pairs are ordered by lat/lon and separated by
|
In GeoRSS coordinate pairs are ordered by lat/lon and separated by
|
||||||
a single white space. Given a tuple of coordinates, this will return
|
a single white space. Given a tuple of coordinates, return a string
|
||||||
a unicode GeoRSS representation.
|
GeoRSS representation.
|
||||||
"""
|
"""
|
||||||
return ' '.join('%f %f' % (coord[1], coord[0]) for coord in coords)
|
return ' '.join('%f %f' % (coord[1], coord[0]) for coord in coords)
|
||||||
|
|
||||||
|
|
|
@ -74,7 +74,7 @@ class Command(BaseCommand):
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--name-field', dest='name_field',
|
'--name-field', dest='name_field',
|
||||||
help='Specifies a field name to return for the `__unicode__`/`__str__` function.',
|
help='Specifies a field name to return for the __str__() method.',
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--no-imports', action='store_false', dest='imports', default=True,
|
'--no-imports', action='store_false', dest='imports', default=True,
|
||||||
|
|
|
@ -92,7 +92,7 @@ def ogrinspect(*args, **kwargs):
|
||||||
`multi_geom` => Boolean (default: False) - specify as multigeometry.
|
`multi_geom` => Boolean (default: False) - specify as multigeometry.
|
||||||
|
|
||||||
`name_field` => String - specifies a field name to return for the
|
`name_field` => String - specifies a field name to return for the
|
||||||
`__unicode__`/`__str__` function (which will be generated if specified).
|
__str__() method (which will be generated if specified).
|
||||||
|
|
||||||
`imports` => Boolean (default: True) - set to False to omit the
|
`imports` => Boolean (default: True) - set to False to omit the
|
||||||
`from django.contrib.gis.db import models` code from the
|
`from django.contrib.gis.db import models` code from the
|
||||||
|
|
|
@ -20,7 +20,7 @@ class Message:
|
||||||
def _prepare(self):
|
def _prepare(self):
|
||||||
"""
|
"""
|
||||||
Prepares the message for serialization by forcing the ``message``
|
Prepares the message for serialization by forcing the ``message``
|
||||||
and ``extra_tags`` to unicode in case they are lazy translations.
|
and ``extra_tags`` to str in case they are lazy translations.
|
||||||
|
|
||||||
Known "safe" types (None, int, etc.) are not converted (see Django's
|
Known "safe" types (None, int, etc.) are not converted (see Django's
|
||||||
``force_text`` implementation for details).
|
``force_text`` implementation for details).
|
||||||
|
|
|
@ -164,7 +164,7 @@ class WSGIHandler(base.BaseHandler):
|
||||||
|
|
||||||
def get_path_info(environ):
|
def get_path_info(environ):
|
||||||
"""
|
"""
|
||||||
Returns the HTTP request's PATH_INFO as a unicode string.
|
Return the HTTP request's PATH_INFO as a string.
|
||||||
"""
|
"""
|
||||||
path_info = get_bytes_from_wsgi(environ, 'PATH_INFO', '/')
|
path_info = get_bytes_from_wsgi(environ, 'PATH_INFO', '/')
|
||||||
|
|
||||||
|
|
|
@ -207,8 +207,8 @@ class EmailMessage:
|
||||||
Initialize a single email message (which can be sent to multiple
|
Initialize a single email message (which can be sent to multiple
|
||||||
recipients).
|
recipients).
|
||||||
|
|
||||||
All strings used to create the message can be unicode strings
|
All string arguments used to create the message can be strings
|
||||||
(or UTF-8 bytestrings). The SafeMIMEText class will handle any
|
or UTF-8 bytestrings. The SafeMIMEText class will handle any
|
||||||
necessary encoding conversions.
|
necessary encoding conversions.
|
||||||
"""
|
"""
|
||||||
if to:
|
if to:
|
||||||
|
@ -425,8 +425,8 @@ class EmailMultiAlternatives(EmailMessage):
|
||||||
Initialize a single email message (which can be sent to multiple
|
Initialize a single email message (which can be sent to multiple
|
||||||
recipients).
|
recipients).
|
||||||
|
|
||||||
All strings used to create the message can be unicode strings (or UTF-8
|
All string arguments used to create the message can be strings or UTF-8
|
||||||
bytestrings). The SafeMIMEText class will handle any necessary encoding
|
bytestrings. The SafeMIMEText class will handle any necessary encoding
|
||||||
conversions.
|
conversions.
|
||||||
"""
|
"""
|
||||||
super().__init__(
|
super().__init__(
|
||||||
|
|
|
@ -133,8 +133,8 @@ def loads(s, key=None, salt='django.core.signing', serializer=JSONSerializer, ma
|
||||||
|
|
||||||
The serializer is expected to accept a bytestring.
|
The serializer is expected to accept a bytestring.
|
||||||
"""
|
"""
|
||||||
# TimestampSigner.unsign always returns unicode but base64 and zlib
|
# TimestampSigner.unsign() returns str but base64 and zlib compression
|
||||||
# compression operate on bytes.
|
# operate on bytes.
|
||||||
base64d = force_bytes(TimestampSigner(key, salt=salt).unsign(s, max_age=max_age))
|
base64d = force_bytes(TimestampSigner(key, salt=salt).unsign(s, max_age=max_age))
|
||||||
decompress = False
|
decompress = False
|
||||||
if base64d[:1] == b'.':
|
if base64d[:1] == b'.':
|
||||||
|
|
|
@ -71,7 +71,7 @@ class RegexValidator:
|
||||||
|
|
||||||
@deconstructible
|
@deconstructible
|
||||||
class URLValidator(RegexValidator):
|
class URLValidator(RegexValidator):
|
||||||
ul = '\u00a1-\uffff' # unicode letters range (must be a unicode string, not a raw string)
|
ul = '\u00a1-\uffff' # unicode letters range (must not be a raw string)
|
||||||
|
|
||||||
# IP patterns
|
# IP patterns
|
||||||
ipv4_re = r'(?:25[0-5]|2[0-4]\d|[0-1]?\d?\d)(?:\.(?:25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}'
|
ipv4_re = r'(?:25[0-5]|2[0-4]\d|[0-1]?\d?\d)(?:\.(?:25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}'
|
||||||
|
|
|
@ -526,7 +526,7 @@ class CursorIterator:
|
||||||
|
|
||||||
def _rowfactory(row, cursor):
|
def _rowfactory(row, cursor):
|
||||||
# Cast numeric values as the appropriate Python type based upon the
|
# Cast numeric values as the appropriate Python type based upon the
|
||||||
# cursor description, and convert strings to unicode.
|
# cursor description.
|
||||||
casted = []
|
casted = []
|
||||||
for value, desc in zip(row, cursor.description):
|
for value, desc in zip(row, cursor.description):
|
||||||
if value is not None and desc[1] is Database.NUMBER:
|
if value is not None and desc[1] is Database.NUMBER:
|
||||||
|
|
|
@ -366,7 +366,7 @@ class Field(RegisterLookupMixin):
|
||||||
Note that the positional or keyword arguments must contain values of the
|
Note that the positional or keyword arguments must contain values of the
|
||||||
following types (including inner values of collection types):
|
following types (including inner values of collection types):
|
||||||
|
|
||||||
* None, bool, str, unicode, int, long, float, complex, set, frozenset, list, tuple, dict
|
* None, bool, str, int, float, complex, set, frozenset, list, tuple, dict
|
||||||
* UUID
|
* UUID
|
||||||
* datetime.datetime (naive), datetime.date
|
* datetime.datetime (naive), datetime.date
|
||||||
* top-level classes, top-level functions - will be referenced by their full import path
|
* top-level classes, top-level functions - will be referenced by their full import path
|
||||||
|
|
|
@ -314,7 +314,7 @@ class FileField(Field):
|
||||||
# needed because we need to consume values that are also sane for a
|
# needed because we need to consume values that are also sane for a
|
||||||
# regular (non Model-) Form to find in its cleaned_data dictionary.
|
# regular (non Model-) Form to find in its cleaned_data dictionary.
|
||||||
if data is not None:
|
if data is not None:
|
||||||
# This value will be converted to unicode and stored in the
|
# This value will be converted to str and stored in the
|
||||||
# database, so leaving False as-is is not acceptable.
|
# database, so leaving False as-is is not acceptable.
|
||||||
if not data:
|
if not data:
|
||||||
data = ''
|
data = ''
|
||||||
|
|
|
@ -229,7 +229,7 @@ class CharField(Field):
|
||||||
self.validators.append(validators.MaxLengthValidator(int(max_length)))
|
self.validators.append(validators.MaxLengthValidator(int(max_length)))
|
||||||
|
|
||||||
def to_python(self, value):
|
def to_python(self, value):
|
||||||
"Returns a Unicode object."
|
"Returns a string."
|
||||||
if value in self.empty_values:
|
if value in self.empty_values:
|
||||||
return self.empty_value
|
return self.empty_value
|
||||||
value = force_text(value)
|
value = force_text(value)
|
||||||
|
@ -799,7 +799,7 @@ class ChoiceField(Field):
|
||||||
choices = property(_get_choices, _set_choices)
|
choices = property(_get_choices, _set_choices)
|
||||||
|
|
||||||
def to_python(self, value):
|
def to_python(self, value):
|
||||||
"Returns a Unicode object."
|
"Return a string."
|
||||||
if value in self.empty_values:
|
if value in self.empty_values:
|
||||||
return ''
|
return ''
|
||||||
return force_text(value)
|
return force_text(value)
|
||||||
|
|
|
@ -200,9 +200,7 @@ class Widget(metaclass=MediaDefiningClass):
|
||||||
return context
|
return context
|
||||||
|
|
||||||
def render(self, name, value, attrs=None, renderer=None):
|
def render(self, name, value, attrs=None, renderer=None):
|
||||||
"""
|
"""Render the widget as an HTML string."""
|
||||||
Returns this Widget rendered as HTML, as a Unicode string.
|
|
||||||
"""
|
|
||||||
context = self.get_context(name, value, attrs)
|
context = self.get_context(name, value, attrs)
|
||||||
return self._render(self.template_name, context, renderer)
|
return self._render(self.template_name, context, renderer)
|
||||||
|
|
||||||
|
|
|
@ -651,7 +651,7 @@ def parse_header(line):
|
||||||
"""
|
"""
|
||||||
Parse the header into a key-value.
|
Parse the header into a key-value.
|
||||||
|
|
||||||
Input (line): bytes, output: unicode for key/name, bytes for value which
|
Input (line): bytes, output: str for key/name, bytes for values which
|
||||||
will be decoded later.
|
will be decoded later.
|
||||||
"""
|
"""
|
||||||
plist = _parse_header_params(b';' + line)
|
plist = _parse_header_params(b';' + line)
|
||||||
|
|
|
@ -354,7 +354,7 @@ class QueryDict(MultiValueDict):
|
||||||
will always return a mutable copy.
|
will always return a mutable copy.
|
||||||
|
|
||||||
Both keys and values set on this class are converted from the given encoding
|
Both keys and values set on this class are converted from the given encoding
|
||||||
(DEFAULT_CHARSET by default) to unicode.
|
(DEFAULT_CHARSET by default) to str.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# These are both reset in __init__, but is specified here at the class
|
# These are both reset in __init__, but is specified here at the class
|
||||||
|
|
|
@ -153,8 +153,10 @@ class Template:
|
||||||
try:
|
try:
|
||||||
template_string = force_text(template_string)
|
template_string = force_text(template_string)
|
||||||
except UnicodeDecodeError:
|
except UnicodeDecodeError:
|
||||||
raise TemplateEncodingError("Templates can only be constructed "
|
raise TemplateEncodingError(
|
||||||
"from unicode or UTF-8 strings.")
|
"Templates can only be constructed from strings or UTF-8 "
|
||||||
|
"bytestrings."
|
||||||
|
)
|
||||||
# If Template is instantiated directly rather than from an Engine and
|
# If Template is instantiated directly rather than from an Engine and
|
||||||
# exactly one Django template engine is configured, use that engine.
|
# exactly one Django template engine is configured, use that engine.
|
||||||
# This is required to preserve backwards-compatibility for direct use
|
# This is required to preserve backwards-compatibility for direct use
|
||||||
|
@ -270,7 +272,7 @@ class Template:
|
||||||
bottom = min(total, line + 1 + context_lines)
|
bottom = min(total, line + 1 + context_lines)
|
||||||
|
|
||||||
# In some rare cases exc_value.args can be empty or an invalid
|
# In some rare cases exc_value.args can be empty or an invalid
|
||||||
# unicode string.
|
# string.
|
||||||
try:
|
try:
|
||||||
message = force_text(exception.args[0])
|
message = force_text(exception.args[0])
|
||||||
except (IndexError, UnicodeDecodeError):
|
except (IndexError, UnicodeDecodeError):
|
||||||
|
@ -980,8 +982,8 @@ class TextNode(Node):
|
||||||
def render_value_in_context(value, context):
|
def render_value_in_context(value, context):
|
||||||
"""
|
"""
|
||||||
Converts any value to a string to become part of a rendered template. This
|
Converts any value to a string to become part of a rendered template. This
|
||||||
means escaping, if required, and conversion to a unicode object. If value
|
means escaping, if required, and conversion to a string. If value is a
|
||||||
is a string, it is expected to have already been translated.
|
string, it's expected to already be translated.
|
||||||
"""
|
"""
|
||||||
value = template_localtime(value, use_tz=context.use_tz)
|
value = template_localtime(value, use_tz=context.use_tz)
|
||||||
value = localize(value, use_l10n=context.use_l10n)
|
value = localize(value, use_l10n=context.use_l10n)
|
||||||
|
|
|
@ -33,9 +33,8 @@ register = Library()
|
||||||
|
|
||||||
def stringfilter(func):
|
def stringfilter(func):
|
||||||
"""
|
"""
|
||||||
Decorator for filters which should only receive unicode objects. The object
|
Decorator for filters which should only receive strings. The object
|
||||||
passed as the first positional argument will be converted to a unicode
|
passed as the first positional argument will be converted to a string.
|
||||||
object.
|
|
||||||
"""
|
"""
|
||||||
def _dec(*args, **kwargs):
|
def _dec(*args, **kwargs):
|
||||||
if args:
|
if args:
|
||||||
|
@ -471,7 +470,7 @@ def safe(value):
|
||||||
def safeseq(value):
|
def safeseq(value):
|
||||||
"""
|
"""
|
||||||
A "safe" filter for sequences. Marks each element in the sequence,
|
A "safe" filter for sequences. Marks each element in the sequence,
|
||||||
individually, as safe, after converting them to unicode. Returns a list
|
individually, as safe, after converting them to strings. Returns a list
|
||||||
with the results.
|
with the results.
|
||||||
"""
|
"""
|
||||||
return [mark_safe(force_text(obj)) for obj in value]
|
return [mark_safe(force_text(obj)) for obj in value]
|
||||||
|
|
|
@ -594,16 +594,9 @@ def strip_quotes(want, got):
|
||||||
s = s.strip()
|
s = s.strip()
|
||||||
return len(s) >= 2 and s[0] == s[-1] and s[0] in ('"', "'")
|
return len(s) >= 2 and s[0] == s[-1] and s[0] in ('"', "'")
|
||||||
|
|
||||||
def is_quoted_unicode(s):
|
|
||||||
s = s.strip()
|
|
||||||
return len(s) >= 3 and s[0] == 'u' and s[1] == s[-1] and s[1] in ('"', "'")
|
|
||||||
|
|
||||||
if is_quoted_string(want) and is_quoted_string(got):
|
if is_quoted_string(want) and is_quoted_string(got):
|
||||||
want = want.strip()[1:-1]
|
want = want.strip()[1:-1]
|
||||||
got = got.strip()[1:-1]
|
got = got.strip()[1:-1]
|
||||||
elif is_quoted_unicode(want) and is_quoted_unicode(got):
|
|
||||||
want = want.strip()[2:-1]
|
|
||||||
got = got.strip()[2:-1]
|
|
||||||
return want, got
|
return want, got
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -85,9 +85,7 @@ class TimeFormat(Formatter):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if hasattr(self.data, 'tzinfo') and self.data.tzinfo:
|
if hasattr(self.data, 'tzinfo') and self.data.tzinfo:
|
||||||
# Have to use tzinfo.tzname and not datetime.tzname
|
return self.data.tzname() or ''
|
||||||
# because datatime.tzname does not expect Unicode
|
|
||||||
return self.data.tzinfo.tzname(self.data) or ""
|
|
||||||
except NotImplementedError:
|
except NotImplementedError:
|
||||||
pass
|
pass
|
||||||
return ""
|
return ""
|
||||||
|
|
|
@ -24,8 +24,8 @@ python_2_unicode_compatible = six.python_2_unicode_compatible
|
||||||
|
|
||||||
def smart_text(s, encoding='utf-8', strings_only=False, errors='strict'):
|
def smart_text(s, encoding='utf-8', strings_only=False, errors='strict'):
|
||||||
"""
|
"""
|
||||||
Returns a text object representing 's' -- unicode on Python 2 and str on
|
Return a string representing 's'. Treat bytestrings using the 'encoding'
|
||||||
Python 3. Treats bytestrings using the 'encoding' codec.
|
codec.
|
||||||
|
|
||||||
If strings_only is True, don't convert (some) non-string-like objects.
|
If strings_only is True, don't convert (some) non-string-like objects.
|
||||||
"""
|
"""
|
||||||
|
@ -78,9 +78,9 @@ def force_text(s, encoding='utf-8', strings_only=False, errors='strict'):
|
||||||
else:
|
else:
|
||||||
# If we get to here, the caller has passed in an Exception
|
# If we get to here, the caller has passed in an Exception
|
||||||
# subclass populated with non-ASCII bytestring data without a
|
# subclass populated with non-ASCII bytestring data without a
|
||||||
# working unicode method. Try to handle this without raising a
|
# working __str__() method. Try to handle this without raising a
|
||||||
# further exception by individually forcing the exception args
|
# further exception by individually forcing the exception args
|
||||||
# to unicode.
|
# to strings.
|
||||||
s = ' '.join(force_text(arg, encoding, strings_only, errors)
|
s = ' '.join(force_text(arg, encoding, strings_only, errors)
|
||||||
for arg in s)
|
for arg in s)
|
||||||
return s
|
return s
|
||||||
|
@ -186,7 +186,7 @@ def uri_to_iri(uri):
|
||||||
This is the algorithm from section 3.2 of RFC 3987.
|
This is the algorithm from section 3.2 of RFC 3987.
|
||||||
|
|
||||||
Takes an URI in ASCII bytes (e.g. '/I%20%E2%99%A5%20Django/') and returns
|
Takes an URI in ASCII bytes (e.g. '/I%20%E2%99%A5%20Django/') and returns
|
||||||
unicode containing the encoded result (e.g. '/I \xe2\x99\xa5 Django/').
|
a string containing the encoded result (e.g. '/I \xe2\x99\xa5 Django/').
|
||||||
"""
|
"""
|
||||||
if uri is None:
|
if uri is None:
|
||||||
return uri
|
return uri
|
||||||
|
@ -231,7 +231,7 @@ def filepath_to_uri(path):
|
||||||
"""Convert a file system path to a URI portion that is suitable for
|
"""Convert a file system path to a URI portion that is suitable for
|
||||||
inclusion in a URL.
|
inclusion in a URL.
|
||||||
|
|
||||||
We are assuming input is either UTF-8 or unicode already.
|
Assume the input is either UTF-8 bytes or a string.
|
||||||
|
|
||||||
This method will encode certain chars that would normally be recognized as
|
This method will encode certain chars that would normally be recognized as
|
||||||
special chars for URIs. Note that this method does not encode the '
|
special chars for URIs. Note that this method does not encode the '
|
||||||
|
|
|
@ -84,25 +84,25 @@ class SyndicationFeed:
|
||||||
def __init__(self, title, link, description, language=None, author_email=None,
|
def __init__(self, title, link, description, language=None, author_email=None,
|
||||||
author_name=None, author_link=None, subtitle=None, categories=None,
|
author_name=None, author_link=None, subtitle=None, categories=None,
|
||||||
feed_url=None, feed_copyright=None, feed_guid=None, ttl=None, **kwargs):
|
feed_url=None, feed_copyright=None, feed_guid=None, ttl=None, **kwargs):
|
||||||
def to_unicode(s):
|
def to_str(s):
|
||||||
return force_text(s, strings_only=True)
|
return force_text(s, strings_only=True)
|
||||||
if categories:
|
if categories:
|
||||||
categories = [force_text(c) for c in categories]
|
categories = [force_text(c) for c in categories]
|
||||||
if ttl is not None:
|
if ttl is not None:
|
||||||
# Force ints to unicode
|
# Force ints to str
|
||||||
ttl = force_text(ttl)
|
ttl = force_text(ttl)
|
||||||
self.feed = {
|
self.feed = {
|
||||||
'title': to_unicode(title),
|
'title': to_str(title),
|
||||||
'link': iri_to_uri(link),
|
'link': iri_to_uri(link),
|
||||||
'description': to_unicode(description),
|
'description': to_str(description),
|
||||||
'language': to_unicode(language),
|
'language': to_str(language),
|
||||||
'author_email': to_unicode(author_email),
|
'author_email': to_str(author_email),
|
||||||
'author_name': to_unicode(author_name),
|
'author_name': to_str(author_name),
|
||||||
'author_link': iri_to_uri(author_link),
|
'author_link': iri_to_uri(author_link),
|
||||||
'subtitle': to_unicode(subtitle),
|
'subtitle': to_str(subtitle),
|
||||||
'categories': categories or (),
|
'categories': categories or (),
|
||||||
'feed_url': iri_to_uri(feed_url),
|
'feed_url': iri_to_uri(feed_url),
|
||||||
'feed_copyright': to_unicode(feed_copyright),
|
'feed_copyright': to_str(feed_copyright),
|
||||||
'id': feed_guid or link,
|
'id': feed_guid or link,
|
||||||
'ttl': ttl,
|
'ttl': ttl,
|
||||||
}
|
}
|
||||||
|
@ -114,33 +114,32 @@ class SyndicationFeed:
|
||||||
unique_id=None, unique_id_is_permalink=None, categories=(),
|
unique_id=None, unique_id_is_permalink=None, categories=(),
|
||||||
item_copyright=None, ttl=None, updateddate=None, enclosures=None, **kwargs):
|
item_copyright=None, ttl=None, updateddate=None, enclosures=None, **kwargs):
|
||||||
"""
|
"""
|
||||||
Adds an item to the feed. All args are expected to be Python Unicode
|
Add an item to the feed. All args are expected to be strings except
|
||||||
objects except pubdate and updateddate, which are datetime.datetime
|
pubdate and updateddate, which are datetime.datetime objects, and
|
||||||
objects, and enclosures, which is an iterable of instances of the
|
enclosures, which is an iterable of instances of the Enclosure class.
|
||||||
Enclosure class.
|
|
||||||
"""
|
"""
|
||||||
def to_unicode(s):
|
def to_str(s):
|
||||||
return force_text(s, strings_only=True)
|
return force_text(s, strings_only=True)
|
||||||
if categories:
|
if categories:
|
||||||
categories = [to_unicode(c) for c in categories]
|
categories = [to_str(c) for c in categories]
|
||||||
if ttl is not None:
|
if ttl is not None:
|
||||||
# Force ints to unicode
|
# Force ints to str
|
||||||
ttl = force_text(ttl)
|
ttl = force_text(ttl)
|
||||||
item = {
|
item = {
|
||||||
'title': to_unicode(title),
|
'title': to_str(title),
|
||||||
'link': iri_to_uri(link),
|
'link': iri_to_uri(link),
|
||||||
'description': to_unicode(description),
|
'description': to_str(description),
|
||||||
'author_email': to_unicode(author_email),
|
'author_email': to_str(author_email),
|
||||||
'author_name': to_unicode(author_name),
|
'author_name': to_str(author_name),
|
||||||
'author_link': iri_to_uri(author_link),
|
'author_link': iri_to_uri(author_link),
|
||||||
'pubdate': pubdate,
|
'pubdate': pubdate,
|
||||||
'updateddate': updateddate,
|
'updateddate': updateddate,
|
||||||
'comments': to_unicode(comments),
|
'comments': to_str(comments),
|
||||||
'unique_id': to_unicode(unique_id),
|
'unique_id': to_str(unique_id),
|
||||||
'unique_id_is_permalink': unique_id_is_permalink,
|
'unique_id_is_permalink': unique_id_is_permalink,
|
||||||
'enclosures': enclosures,
|
'enclosures': enclosures,
|
||||||
'categories': categories or (),
|
'categories': categories or (),
|
||||||
'item_copyright': to_unicode(item_copyright),
|
'item_copyright': to_str(item_copyright),
|
||||||
'ttl': ttl,
|
'ttl': ttl,
|
||||||
}
|
}
|
||||||
item.update(kwargs)
|
item.update(kwargs)
|
||||||
|
@ -212,7 +211,7 @@ class SyndicationFeed:
|
||||||
class Enclosure:
|
class Enclosure:
|
||||||
"Represents an RSS enclosure"
|
"Represents an RSS enclosure"
|
||||||
def __init__(self, url, length, mime_type):
|
def __init__(self, url, length, mime_type):
|
||||||
"All args are expected to be Python Unicode objects"
|
"All args are expected to be strings"
|
||||||
self.length, self.mime_type = length, mime_type
|
self.length, self.mime_type = length, mime_type
|
||||||
self.url = iri_to_uri(url)
|
self.url = iri_to_uri(url)
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@ class SafeBytes(bytes, SafeData):
|
||||||
def __add__(self, rhs):
|
def __add__(self, rhs):
|
||||||
"""
|
"""
|
||||||
Concatenating a safe byte string with another safe byte string or safe
|
Concatenating a safe byte string with another safe byte string or safe
|
||||||
unicode string is safe. Otherwise, the result is no longer safe.
|
string is safe. Otherwise, the result is no longer safe.
|
||||||
"""
|
"""
|
||||||
t = super().__add__(rhs)
|
t = super().__add__(rhs)
|
||||||
if isinstance(rhs, SafeText):
|
if isinstance(rhs, SafeText):
|
||||||
|
@ -37,9 +37,8 @@ class SafeBytes(bytes, SafeData):
|
||||||
|
|
||||||
def _proxy_method(self, *args, **kwargs):
|
def _proxy_method(self, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
Wrap a call to a normal unicode method up so that we return safe
|
Wrap a call to a normal bytes method up so that the result is safe.
|
||||||
results. The method that is being wrapped is passed in the 'method'
|
The method that is being wrapped is passed in the 'method' argument.
|
||||||
argument.
|
|
||||||
"""
|
"""
|
||||||
method = kwargs.pop('method')
|
method = kwargs.pop('method')
|
||||||
data = method(self, *args, **kwargs)
|
data = method(self, *args, **kwargs)
|
||||||
|
@ -58,8 +57,8 @@ class SafeText(str, SafeData):
|
||||||
"""
|
"""
|
||||||
def __add__(self, rhs):
|
def __add__(self, rhs):
|
||||||
"""
|
"""
|
||||||
Concatenating a safe unicode string with another safe byte string or
|
Concatenating a safe string with another safe byte string or
|
||||||
safe unicode string is safe. Otherwise, the result is no longer safe.
|
safe string is safe. Otherwise, the result is no longer safe.
|
||||||
"""
|
"""
|
||||||
t = super().__add__(rhs)
|
t = super().__add__(rhs)
|
||||||
if isinstance(rhs, SafeData):
|
if isinstance(rhs, SafeData):
|
||||||
|
@ -68,9 +67,8 @@ class SafeText(str, SafeData):
|
||||||
|
|
||||||
def _proxy_method(self, *args, **kwargs):
|
def _proxy_method(self, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
Wrap a call to a normal unicode method up so that we return safe
|
Wrap a call to a normal str method up so that the result is safe.
|
||||||
results. The method that is being wrapped is passed in the 'method'
|
The method that is being wrapped is passed in the 'method' argument.
|
||||||
argument.
|
|
||||||
"""
|
"""
|
||||||
method = kwargs.pop('method')
|
method = kwargs.pop('method')
|
||||||
data = method(self, *args, **kwargs)
|
data = method(self, *args, **kwargs)
|
||||||
|
|
|
@ -230,7 +230,7 @@ def get_valid_filename(s):
|
||||||
"""
|
"""
|
||||||
Returns the given string converted to a string that can be used for a clean
|
Returns the given string converted to a string that can be used for a clean
|
||||||
filename. Specifically, leading and trailing spaces are removed; other
|
filename. Specifically, leading and trailing spaces are removed; other
|
||||||
spaces are converted to underscores; and anything that is not a unicode
|
spaces are converted to underscores; and anything that is not an
|
||||||
alphanumeric, dash, underscore, or dot, is removed.
|
alphanumeric, dash, underscore, or dot, is removed.
|
||||||
>>> get_valid_filename("john's portrait in 2004.jpg")
|
>>> get_valid_filename("john's portrait in 2004.jpg")
|
||||||
'johns_portrait_in_2004.jpg'
|
'johns_portrait_in_2004.jpg'
|
||||||
|
|
|
@ -54,8 +54,7 @@ def templatize(src, origin=None, charset='utf-8'):
|
||||||
comment = []
|
comment = []
|
||||||
lineno_comment_map = {}
|
lineno_comment_map = {}
|
||||||
comment_lineno_cache = None
|
comment_lineno_cache = None
|
||||||
# Adding the u prefix allows gettext to recognize the Unicode string
|
# Adding the u prefix allows gettext to recognize the string (#26093).
|
||||||
# (#26093).
|
|
||||||
raw_prefix = 'u'
|
raw_prefix = 'u'
|
||||||
|
|
||||||
def join_tokens(tokens, trim=False):
|
def join_tokens(tokens, trim=False):
|
||||||
|
|
|
@ -337,7 +337,7 @@ def pgettext(context, message):
|
||||||
result = ugettext(msg_with_ctxt)
|
result = ugettext(msg_with_ctxt)
|
||||||
if CONTEXT_SEPARATOR in result:
|
if CONTEXT_SEPARATOR in result:
|
||||||
# Translation not found
|
# Translation not found
|
||||||
# force unicode, because lazy version expects unicode
|
# force str, because the lazy version expects str.
|
||||||
result = force_text(message)
|
result = force_text(message)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
|
@ -263,7 +263,7 @@ class ExceptionReporter:
|
||||||
frame_vars = []
|
frame_vars = []
|
||||||
for k, v in frame['vars']:
|
for k, v in frame['vars']:
|
||||||
v = pprint(v)
|
v = pprint(v)
|
||||||
# The force_escape filter assume unicode, make sure that works
|
# The force_escape filter assumes str, make sure that works
|
||||||
if isinstance(v, bytes):
|
if isinstance(v, bytes):
|
||||||
v = v.decode('utf-8', 'replace') # don't choke on non-utf-8 input
|
v = v.decode('utf-8', 'replace') # don't choke on non-utf-8 input
|
||||||
# Trim large blobs of data
|
# Trim large blobs of data
|
||||||
|
@ -360,7 +360,7 @@ class ExceptionReporter:
|
||||||
return None, [], None, []
|
return None, [], None, []
|
||||||
|
|
||||||
# If we just read the source from a file, or if the loader did not
|
# If we just read the source from a file, or if the loader did not
|
||||||
# apply tokenize.detect_encoding to decode the source into a Unicode
|
# apply tokenize.detect_encoding to decode the source into a
|
||||||
# string, then we should do that ourselves.
|
# string, then we should do that ourselves.
|
||||||
if isinstance(source[0], bytes):
|
if isinstance(source[0], bytes):
|
||||||
encoding = 'ascii'
|
encoding = 'ascii'
|
||||||
|
|
|
@ -305,7 +305,7 @@ the :meth:`~BaseCommand.handle` method must be implemented.
|
||||||
|
|
||||||
The actual logic of the command. Subclasses must implement this method.
|
The actual logic of the command. Subclasses must implement this method.
|
||||||
|
|
||||||
It may return a Unicode string which will be printed to ``stdout`` (wrapped
|
It may return a string which will be printed to ``stdout`` (wrapped
|
||||||
by ``BEGIN;`` and ``COMMIT;`` if :attr:`output_transaction` is ``True``).
|
by ``BEGIN;`` and ``COMMIT;`` if :attr:`output_transaction` is ``True``).
|
||||||
|
|
||||||
.. method:: BaseCommand.check(app_configs=None, tags=None, display_num_errors=False)
|
.. method:: BaseCommand.check(app_configs=None, tags=None, display_num_errors=False)
|
||||||
|
|
|
@ -188,12 +188,11 @@ Filters and auto-escaping
|
||||||
-------------------------
|
-------------------------
|
||||||
|
|
||||||
When writing a custom filter, give some thought to how the filter will interact
|
When writing a custom filter, give some thought to how the filter will interact
|
||||||
with Django's auto-escaping behavior. Note that three types of strings can be
|
with Django's auto-escaping behavior. Note that two types of strings can be
|
||||||
passed around inside the template code:
|
passed around inside the template code:
|
||||||
|
|
||||||
* **Raw strings** are the native Python ``str`` or ``unicode`` types. On
|
* **Raw strings** are the native Python strings. On output, they're escaped if
|
||||||
output, they're escaped if auto-escaping is in effect and presented
|
auto-escaping is in effect and presented unchanged, otherwise.
|
||||||
unchanged, otherwise.
|
|
||||||
|
|
||||||
* **Safe strings** are strings that have been marked safe from further
|
* **Safe strings** are strings that have been marked safe from further
|
||||||
escaping at output time. Any necessary escaping has already been done.
|
escaping at output time. Any necessary escaping has already been done.
|
||||||
|
@ -229,9 +228,8 @@ Template filter code falls into one of two situations:
|
||||||
|
|
||||||
The reason ``is_safe`` is necessary is because there are plenty of
|
The reason ``is_safe`` is necessary is because there are plenty of
|
||||||
normal string operations that will turn a ``SafeData`` object back into
|
normal string operations that will turn a ``SafeData`` object back into
|
||||||
a normal ``str`` or ``unicode`` object and, rather than try to catch
|
a normal ``str`` object and, rather than try to catch them all, which would
|
||||||
them all, which would be very difficult, Django repairs the damage after
|
be very difficult, Django repairs the damage after the filter has completed.
|
||||||
the filter has completed.
|
|
||||||
|
|
||||||
For example, suppose you have a filter that adds the string ``xx`` to
|
For example, suppose you have a filter that adds the string ``xx`` to
|
||||||
the end of any input. Since this introduces no dangerous HTML characters
|
the end of any input. Since this introduces no dangerous HTML characters
|
||||||
|
|
|
@ -197,14 +197,14 @@ given ``geo_input`` argument, and then assumes the proper geometry subclass
|
||||||
The following input formats, along with their corresponding Python types,
|
The following input formats, along with their corresponding Python types,
|
||||||
are accepted:
|
are accepted:
|
||||||
|
|
||||||
======================= ======================
|
======================= ==========
|
||||||
Format Input Type
|
Format Input Type
|
||||||
======================= ======================
|
======================= ==========
|
||||||
WKT / EWKT ``str`` or ``unicode``
|
WKT / EWKT ``str``
|
||||||
HEX / HEXEWKB ``str`` or ``unicode``
|
HEX / HEXEWKB ``str``
|
||||||
WKB / EWKB ``buffer``
|
WKB / EWKB ``buffer``
|
||||||
GeoJSON ``str`` or ``unicode``
|
GeoJSON ``str``
|
||||||
======================= ======================
|
======================= ==========
|
||||||
|
|
||||||
.. classmethod:: GEOSGeometry.from_gml(gml_string)
|
.. classmethod:: GEOSGeometry.from_gml(gml_string)
|
||||||
|
|
||||||
|
|
|
@ -114,7 +114,7 @@ into those elements.
|
||||||
calling the methods ``item_title()`` and ``item_description()`` on
|
calling the methods ``item_title()`` and ``item_description()`` on
|
||||||
the :class:`~django.contrib.syndication.views.Feed` class. They are passed
|
the :class:`~django.contrib.syndication.views.Feed` class. They are passed
|
||||||
a single parameter, ``item``, which is the object itself. These are
|
a single parameter, ``item``, which is the object itself. These are
|
||||||
optional; by default, the unicode representation of the object is used for
|
optional; by default, the string representation of the object is used for
|
||||||
both.
|
both.
|
||||||
|
|
||||||
If you want to do any special formatting for either the title or
|
If you want to do any special formatting for either the title or
|
||||||
|
@ -615,7 +615,7 @@ This example illustrates all possible attributes and methods for a
|
||||||
|
|
||||||
# ITEM TITLE AND DESCRIPTION -- If title_template or
|
# ITEM TITLE AND DESCRIPTION -- If title_template or
|
||||||
# description_template are not defined, these are used instead. Both are
|
# description_template are not defined, these are used instead. Both are
|
||||||
# optional, by default they will use the unicode representation of the
|
# optional, by default they will use the string representation of the
|
||||||
# item.
|
# item.
|
||||||
|
|
||||||
def item_title(self, item):
|
def item_title(self, item):
|
||||||
|
@ -940,8 +940,8 @@ They share this interface:
|
||||||
Any extra keyword arguments you pass to ``__init__`` will be stored in
|
Any extra keyword arguments you pass to ``__init__`` will be stored in
|
||||||
``self.feed`` for use with `custom feed generators`_.
|
``self.feed`` for use with `custom feed generators`_.
|
||||||
|
|
||||||
All parameters should be Unicode objects, except ``categories``, which
|
All parameters should be strings, except ``categories``, which should be a
|
||||||
should be a sequence of Unicode objects. Beware that some control characters
|
sequence of strings. Beware that some control characters
|
||||||
are `not allowed <http://www.w3.org/International/questions/qa-controls>`_
|
are `not allowed <http://www.w3.org/International/questions/qa-controls>`_
|
||||||
in XML documents. If your content has some of them, you might encounter a
|
in XML documents. If your content has some of them, you might encounter a
|
||||||
:exc:`ValueError` when producing the feed.
|
:exc:`ValueError` when producing the feed.
|
||||||
|
@ -971,13 +971,13 @@ They share this interface:
|
||||||
|
|
||||||
Extra keyword arguments will be stored for `custom feed generators`_.
|
Extra keyword arguments will be stored for `custom feed generators`_.
|
||||||
|
|
||||||
All parameters, if given, should be Unicode objects, except:
|
All parameters, if given, should be strings, except:
|
||||||
|
|
||||||
* ``pubdate`` should be a Python :class:`~datetime.datetime` object.
|
* ``pubdate`` should be a Python :class:`~datetime.datetime` object.
|
||||||
* ``updateddate`` should be a Python :class:`~datetime.datetime` object.
|
* ``updateddate`` should be a Python :class:`~datetime.datetime` object.
|
||||||
* ``enclosures`` should be a list of
|
* ``enclosures`` should be a list of
|
||||||
:class:`django.utils.feedgenerator.Enclosure` instances.
|
:class:`django.utils.feedgenerator.Enclosure` instances.
|
||||||
* ``categories`` should be a sequence of Unicode objects.
|
* ``categories`` should be a sequence of strings.
|
||||||
|
|
||||||
:meth:`.SyndicationFeed.write`
|
:meth:`.SyndicationFeed.write`
|
||||||
Outputs the feed in the given encoding to outfile, which is a file-like object.
|
Outputs the feed in the given encoding to outfile, which is a file-like object.
|
||||||
|
|
|
@ -196,7 +196,7 @@ attributes:
|
||||||
|
|
||||||
``field_name`` is a string name of the file ``<input>`` field.
|
``field_name`` is a string name of the file ``<input>`` field.
|
||||||
|
|
||||||
``file_name`` is the unicode filename that was provided by the browser.
|
``file_name`` is the filename provided by the browser.
|
||||||
|
|
||||||
``content_type`` is the MIME type provided by the browser -- E.g.
|
``content_type`` is the MIME type provided by the browser -- E.g.
|
||||||
``'image/jpeg'``.
|
``'image/jpeg'``.
|
||||||
|
|
|
@ -112,7 +112,7 @@ messages::
|
||||||
{'sender': ['Enter a valid email address.'], 'subject': ['This field is required.']}
|
{'sender': ['Enter a valid email address.'], 'subject': ['This field is required.']}
|
||||||
|
|
||||||
In this dictionary, the keys are the field names, and the values are lists of
|
In this dictionary, the keys are the field names, and the values are lists of
|
||||||
Unicode strings representing the error messages. The error messages are stored
|
strings representing the error messages. The error messages are stored
|
||||||
in lists because a field can have multiple error messages.
|
in lists because a field can have multiple error messages.
|
||||||
|
|
||||||
You can access :attr:`~Form.errors` without having to call
|
You can access :attr:`~Form.errors` without having to call
|
||||||
|
@ -357,8 +357,8 @@ it, you can access the clean data via its ``cleaned_data`` attribute::
|
||||||
{'cc_myself': True, 'message': 'Hi there', 'sender': 'foo@example.com', 'subject': 'hello'}
|
{'cc_myself': True, 'message': 'Hi there', 'sender': 'foo@example.com', 'subject': 'hello'}
|
||||||
|
|
||||||
Note that any text-based field -- such as ``CharField`` or ``EmailField`` --
|
Note that any text-based field -- such as ``CharField`` or ``EmailField`` --
|
||||||
always cleans the input into a Unicode string. We'll cover the encoding
|
always cleans the input into a string. We'll cover the encoding implications
|
||||||
implications later in this document.
|
later in this document.
|
||||||
|
|
||||||
If your data does *not* validate, the ``cleaned_data`` dictionary contains
|
If your data does *not* validate, the ``cleaned_data`` dictionary contains
|
||||||
only the valid fields::
|
only the valid fields::
|
||||||
|
@ -490,7 +490,7 @@ Notice the following:
|
||||||
|
|
||||||
Although ``<table>`` output is the default output style when you ``print`` a
|
Although ``<table>`` output is the default output style when you ``print`` a
|
||||||
form, other output styles are available. Each style is available as a method on
|
form, other output styles are available. Each style is available as a method on
|
||||||
a form object, and each rendering method returns a Unicode object.
|
a form object, and each rendering method returns a string.
|
||||||
|
|
||||||
``as_p()``
|
``as_p()``
|
||||||
----------
|
----------
|
||||||
|
|
|
@ -88,9 +88,8 @@ To specify that a field is *not* required, pass ``required=False`` to the
|
||||||
|
|
||||||
If a ``Field`` has ``required=False`` and you pass ``clean()`` an empty value,
|
If a ``Field`` has ``required=False`` and you pass ``clean()`` an empty value,
|
||||||
then ``clean()`` will return a *normalized* empty value rather than raising
|
then ``clean()`` will return a *normalized* empty value rather than raising
|
||||||
``ValidationError``. For ``CharField``, this will be a Unicode empty string.
|
``ValidationError``. For ``CharField``, this will be an empty string. For other
|
||||||
For other ``Field`` classes, it might be ``None``. (This varies from field to
|
``Field`` classes, it might be ``None``. (This varies from field to field.)
|
||||||
field.)
|
|
||||||
|
|
||||||
Widgets of required form fields have the ``required`` HTML attribute. Set the
|
Widgets of required form fields have the ``required`` HTML attribute. Set the
|
||||||
:attr:`Form.use_required_attribute` attribute to ``False`` to disable it. The
|
:attr:`Form.use_required_attribute` attribute to ``False`` to disable it. The
|
||||||
|
@ -371,7 +370,7 @@ For each field, we describe the default widget used if you don't specify
|
||||||
|
|
||||||
* Default widget: :class:`TextInput`
|
* Default widget: :class:`TextInput`
|
||||||
* Empty value: Whatever you've given as :attr:`empty_value`.
|
* Empty value: Whatever you've given as :attr:`empty_value`.
|
||||||
* Normalizes to: A Unicode object.
|
* Normalizes to: A string.
|
||||||
* Validates ``max_length`` or ``min_length``, if they are provided.
|
* Validates ``max_length`` or ``min_length``, if they are provided.
|
||||||
Otherwise, all inputs are valid.
|
Otherwise, all inputs are valid.
|
||||||
* Error message keys: ``required``, ``max_length``, ``min_length``
|
* Error message keys: ``required``, ``max_length``, ``min_length``
|
||||||
|
@ -402,7 +401,7 @@ For each field, we describe the default widget used if you don't specify
|
||||||
|
|
||||||
* Default widget: :class:`Select`
|
* Default widget: :class:`Select`
|
||||||
* Empty value: ``''`` (an empty string)
|
* Empty value: ``''`` (an empty string)
|
||||||
* Normalizes to: A Unicode object.
|
* Normalizes to: A string.
|
||||||
* Validates that the given value exists in the list of choices.
|
* Validates that the given value exists in the list of choices.
|
||||||
* Error message keys: ``required``, ``invalid_choice``
|
* Error message keys: ``required``, ``invalid_choice``
|
||||||
|
|
||||||
|
@ -585,7 +584,7 @@ For each field, we describe the default widget used if you don't specify
|
||||||
|
|
||||||
* Default widget: :class:`EmailInput`
|
* Default widget: :class:`EmailInput`
|
||||||
* Empty value: ``''`` (an empty string)
|
* Empty value: ``''`` (an empty string)
|
||||||
* Normalizes to: A Unicode object.
|
* Normalizes to: A string.
|
||||||
* Validates that the given value is a valid email address, using a
|
* Validates that the given value is a valid email address, using a
|
||||||
moderately complex regular expression.
|
moderately complex regular expression.
|
||||||
* Error message keys: ``required``, ``invalid``
|
* Error message keys: ``required``, ``invalid``
|
||||||
|
@ -629,7 +628,7 @@ For each field, we describe the default widget used if you don't specify
|
||||||
|
|
||||||
* Default widget: :class:`Select`
|
* Default widget: :class:`Select`
|
||||||
* Empty value: ``None``
|
* Empty value: ``None``
|
||||||
* Normalizes to: A unicode object
|
* Normalizes to: A string.
|
||||||
* Validates that the selected choice exists in the list of choices.
|
* Validates that the selected choice exists in the list of choices.
|
||||||
* Error message keys: ``required``, ``invalid_choice``
|
* Error message keys: ``required``, ``invalid_choice``
|
||||||
|
|
||||||
|
@ -747,8 +746,7 @@ For each field, we describe the default widget used if you don't specify
|
||||||
|
|
||||||
* Default widget: :class:`TextInput`
|
* Default widget: :class:`TextInput`
|
||||||
* Empty value: ``''`` (an empty string)
|
* Empty value: ``''`` (an empty string)
|
||||||
* Normalizes to: A Unicode object. IPv6 addresses are
|
* Normalizes to: A string. IPv6 addresses are normalized as described below.
|
||||||
normalized as described below.
|
|
||||||
* Validates that the given value is a valid IP address.
|
* Validates that the given value is a valid IP address.
|
||||||
* Error message keys: ``required``, ``invalid``
|
* Error message keys: ``required``, ``invalid``
|
||||||
|
|
||||||
|
@ -780,7 +778,7 @@ For each field, we describe the default widget used if you don't specify
|
||||||
|
|
||||||
* Default widget: :class:`SelectMultiple`
|
* Default widget: :class:`SelectMultiple`
|
||||||
* Empty value: ``[]`` (an empty list)
|
* Empty value: ``[]`` (an empty list)
|
||||||
* Normalizes to: A list of Unicode objects.
|
* Normalizes to: A list of strings.
|
||||||
* Validates that every value in the given list of values exists in the list
|
* Validates that every value in the given list of values exists in the list
|
||||||
of choices.
|
of choices.
|
||||||
* Error message keys: ``required``, ``invalid_choice``, ``invalid_list``
|
* Error message keys: ``required``, ``invalid_choice``, ``invalid_list``
|
||||||
|
@ -829,7 +827,7 @@ For each field, we describe the default widget used if you don't specify
|
||||||
|
|
||||||
* Default widget: :class:`TextInput`
|
* Default widget: :class:`TextInput`
|
||||||
* Empty value: ``''`` (an empty string)
|
* Empty value: ``''`` (an empty string)
|
||||||
* Normalizes to: A Unicode object.
|
* Normalizes to: A string.
|
||||||
* Validates that the given value matches against a certain regular
|
* Validates that the given value matches against a certain regular
|
||||||
expression.
|
expression.
|
||||||
* Error message keys: ``required``, ``invalid``
|
* Error message keys: ``required``, ``invalid``
|
||||||
|
@ -856,7 +854,7 @@ For each field, we describe the default widget used if you don't specify
|
||||||
|
|
||||||
* Default widget: :class:`TextInput`
|
* Default widget: :class:`TextInput`
|
||||||
* Empty value: ``''`` (an empty string)
|
* Empty value: ``''`` (an empty string)
|
||||||
* Normalizes to: A Unicode object.
|
* Normalizes to: A string.
|
||||||
* Validates that the given value contains only letters, numbers,
|
* Validates that the given value contains only letters, numbers,
|
||||||
underscores, and hyphens.
|
underscores, and hyphens.
|
||||||
* Error messages: ``required``, ``invalid``
|
* Error messages: ``required``, ``invalid``
|
||||||
|
@ -902,7 +900,7 @@ For each field, we describe the default widget used if you don't specify
|
||||||
|
|
||||||
* Default widget: :class:`URLInput`
|
* Default widget: :class:`URLInput`
|
||||||
* Empty value: ``''`` (an empty string)
|
* Empty value: ``''`` (an empty string)
|
||||||
* Normalizes to: A Unicode object.
|
* Normalizes to: A string.
|
||||||
* Validates that the given value is a valid URL.
|
* Validates that the given value is a valid URL.
|
||||||
* Error message keys: ``required``, ``invalid``
|
* Error message keys: ``required``, ``invalid``
|
||||||
|
|
||||||
|
@ -936,7 +934,7 @@ Slightly complex built-in ``Field`` classes
|
||||||
|
|
||||||
* Default widget: :class:`TextInput`
|
* Default widget: :class:`TextInput`
|
||||||
* Empty value: ``''`` (an empty string)
|
* Empty value: ``''`` (an empty string)
|
||||||
* Normalizes to: A Unicode object.
|
* Normalizes to: A string.
|
||||||
* Validates the given value against each of the fields specified
|
* Validates the given value against each of the fields specified
|
||||||
as an argument to the ``ComboField``.
|
as an argument to the ``ComboField``.
|
||||||
* Error message keys: ``required``, ``invalid``
|
* Error message keys: ``required``, ``invalid``
|
||||||
|
|
|
@ -2391,10 +2391,9 @@ Note the first query will match ``'Beatles Blog'``, ``'beatles blog'``,
|
||||||
|
|
||||||
.. admonition:: SQLite users
|
.. admonition:: SQLite users
|
||||||
|
|
||||||
When using the SQLite backend and Unicode (non-ASCII) strings, bear in
|
When using the SQLite backend and non-ASCII strings, bear in mind the
|
||||||
mind the :ref:`database note <sqlite-string-matching>` about string
|
:ref:`database note <sqlite-string-matching>` about string comparisons.
|
||||||
comparisons. SQLite does not do case-insensitive matching for Unicode
|
SQLite does not do case-insensitive matching for non-ASCII strings.
|
||||||
strings.
|
|
||||||
|
|
||||||
.. fieldlookup:: contains
|
.. fieldlookup:: contains
|
||||||
|
|
||||||
|
@ -2438,9 +2437,8 @@ SQL equivalent::
|
||||||
|
|
||||||
.. admonition:: SQLite users
|
.. admonition:: SQLite users
|
||||||
|
|
||||||
When using the SQLite backend and Unicode (non-ASCII) strings, bear in
|
When using the SQLite backend and non-ASCII strings, bear in mind the
|
||||||
mind the :ref:`database note <sqlite-string-matching>` about string
|
:ref:`database note <sqlite-string-matching>` about string comparisons.
|
||||||
comparisons.
|
|
||||||
|
|
||||||
.. fieldlookup:: in
|
.. fieldlookup:: in
|
||||||
|
|
||||||
|
@ -2572,9 +2570,8 @@ SQL equivalent::
|
||||||
|
|
||||||
.. admonition:: SQLite users
|
.. admonition:: SQLite users
|
||||||
|
|
||||||
When using the SQLite backend and Unicode (non-ASCII) strings, bear in
|
When using the SQLite backend and non-ASCII strings, bear in mind the
|
||||||
mind the :ref:`database note <sqlite-string-matching>` about string
|
:ref:`database note <sqlite-string-matching>` about string comparisons.
|
||||||
comparisons.
|
|
||||||
|
|
||||||
.. fieldlookup:: endswith
|
.. fieldlookup:: endswith
|
||||||
|
|
||||||
|
@ -2614,9 +2611,8 @@ SQL equivalent::
|
||||||
|
|
||||||
.. admonition:: SQLite users
|
.. admonition:: SQLite users
|
||||||
|
|
||||||
When using the SQLite backend and Unicode (non-ASCII) strings, bear in
|
When using the SQLite backend and non-ASCII strings, bear in mind the
|
||||||
mind the :ref:`database note <sqlite-string-matching>` about string
|
:ref:`database note <sqlite-string-matching>` about string comparisons.
|
||||||
comparisons.
|
|
||||||
|
|
||||||
.. fieldlookup:: range
|
.. fieldlookup:: range
|
||||||
|
|
||||||
|
|
|
@ -416,7 +416,7 @@ a subclass of dictionary. Exceptions are outlined here:
|
||||||
``mutable=True`` to its ``__init__()``.
|
``mutable=True`` to its ``__init__()``.
|
||||||
|
|
||||||
Strings for setting both keys and values will be converted from ``encoding``
|
Strings for setting both keys and values will be converted from ``encoding``
|
||||||
to unicode. If encoding is not set, it defaults to :setting:`DEFAULT_CHARSET`.
|
to ``str``. If encoding is not set, it defaults to :setting:`DEFAULT_CHARSET`.
|
||||||
|
|
||||||
.. classmethod:: QueryDict.fromkeys(iterable, value='', mutable=False, encoding=None)
|
.. classmethod:: QueryDict.fromkeys(iterable, value='', mutable=False, encoding=None)
|
||||||
|
|
||||||
|
@ -654,8 +654,7 @@ Attributes
|
||||||
|
|
||||||
.. attribute:: HttpResponse.content
|
.. attribute:: HttpResponse.content
|
||||||
|
|
||||||
A bytestring representing the content, encoded from a Unicode
|
A bytestring representing the content, encoded from a string if necessary.
|
||||||
object if necessary.
|
|
||||||
|
|
||||||
.. attribute:: HttpResponse.charset
|
.. attribute:: HttpResponse.charset
|
||||||
|
|
||||||
|
|
|
@ -1934,8 +1934,7 @@ If ``value`` is ``Totally LOVING this Album!``, the output will be
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
Returns the value turned into a list. For a string, it's a list of characters.
|
Returns the value turned into a list. For a string, it's a list of characters.
|
||||||
For an integer, the argument is cast into an unicode string before creating a
|
For an integer, the argument is cast to a string before creating a list.
|
||||||
list.
|
|
||||||
|
|
||||||
For example::
|
For example::
|
||||||
|
|
||||||
|
|
|
@ -3,8 +3,8 @@ Unicode data
|
||||||
============
|
============
|
||||||
|
|
||||||
Django natively supports Unicode data everywhere. Providing your database can
|
Django natively supports Unicode data everywhere. Providing your database can
|
||||||
somehow store the data, you can safely pass around Unicode strings to
|
somehow store the data, you can safely pass around strings to templates,
|
||||||
templates, models and the database.
|
models, and the database.
|
||||||
|
|
||||||
This document tells you what you need to know if you're writing applications
|
This document tells you what you need to know if you're writing applications
|
||||||
that use data or templates that are encoded in something other than ASCII.
|
that use data or templates that are encoded in something other than ASCII.
|
||||||
|
@ -35,11 +35,10 @@ able to store certain characters in the database, and information will be lost.
|
||||||
.. _section 2: https://docs.oracle.com/database/121/NLSPG/ch2charset.htm#NLSPG002
|
.. _section 2: https://docs.oracle.com/database/121/NLSPG/ch2charset.htm#NLSPG002
|
||||||
.. _section 11: https://docs.oracle.com/database/121/NLSPG/ch11charsetmig.htm#NLSPG011
|
.. _section 11: https://docs.oracle.com/database/121/NLSPG/ch11charsetmig.htm#NLSPG011
|
||||||
|
|
||||||
All of Django's database backends automatically convert Unicode strings into
|
All of Django's database backends automatically convert strings into
|
||||||
the appropriate encoding for talking to the database. They also automatically
|
the appropriate encoding for talking to the database. They also automatically
|
||||||
convert strings retrieved from the database into Python Unicode strings. You
|
convert strings retrieved from the database into strings. You don't even need
|
||||||
don't even need to tell Django what encoding your database uses: that is
|
to tell Django what encoding your database uses: that is handled transparently.
|
||||||
handled transparently.
|
|
||||||
|
|
||||||
For more, see the section "The database API" below.
|
For more, see the section "The database API" below.
|
||||||
|
|
||||||
|
@ -48,7 +47,7 @@ General string handling
|
||||||
|
|
||||||
Whenever you use strings with Django -- e.g., in database lookups, template
|
Whenever you use strings with Django -- e.g., in database lookups, template
|
||||||
rendering or anywhere else -- you have two choices for encoding those strings.
|
rendering or anywhere else -- you have two choices for encoding those strings.
|
||||||
You can use normal Unicode strings or bytestrings (starting with a 'b').
|
You can use normal strings or bytestrings (starting with a 'b').
|
||||||
|
|
||||||
.. warning::
|
.. warning::
|
||||||
|
|
||||||
|
@ -74,13 +73,13 @@ using your application -- and if that person chooses a different setting, your
|
||||||
code must still continue to work. Ergo, it cannot rely on that setting.
|
code must still continue to work. Ergo, it cannot rely on that setting.
|
||||||
|
|
||||||
In most cases when Django is dealing with strings, it will convert them to
|
In most cases when Django is dealing with strings, it will convert them to
|
||||||
Unicode strings before doing anything else. So, as a general rule, if you pass
|
strings before doing anything else. So, as a general rule, if you pass
|
||||||
in a bytestring, be prepared to receive a Unicode string back in the result.
|
in a bytestring, be prepared to receive a string back in the result.
|
||||||
|
|
||||||
Translated strings
|
Translated strings
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
Aside from Unicode strings and bytestrings, there's a third type of string-like
|
Aside from strings and bytestrings, there's a third type of string-like
|
||||||
object you may encounter when using Django. The framework's
|
object you may encounter when using Django. The framework's
|
||||||
internationalization features introduce the concept of a "lazy translation" --
|
internationalization features introduce the concept of a "lazy translation" --
|
||||||
a string that has been marked as translated but whose actual translation result
|
a string that has been marked as translated but whose actual translation result
|
||||||
|
@ -93,7 +92,7 @@ Normally, you won't have to worry about lazy translations. Just be aware that
|
||||||
if you examine an object and it claims to be a
|
if you examine an object and it claims to be a
|
||||||
``django.utils.functional.__proxy__`` object, it is a lazy translation.
|
``django.utils.functional.__proxy__`` object, it is a lazy translation.
|
||||||
Calling ``str()`` with the lazy translation as the argument will generate a
|
Calling ``str()`` with the lazy translation as the argument will generate a
|
||||||
Unicode string in the current locale.
|
string in the current locale.
|
||||||
|
|
||||||
For more details about lazy translation objects, refer to the
|
For more details about lazy translation objects, refer to the
|
||||||
:doc:`internationalization </topics/i18n/index>` documentation.
|
:doc:`internationalization </topics/i18n/index>` documentation.
|
||||||
|
@ -102,17 +101,17 @@ Useful utility functions
|
||||||
------------------------
|
------------------------
|
||||||
|
|
||||||
Because some string operations come up again and again, Django ships with a few
|
Because some string operations come up again and again, Django ships with a few
|
||||||
useful functions that should make working with Unicode and bytestring objects
|
useful functions that should make working with string and bytestring objects
|
||||||
a bit easier.
|
a bit easier.
|
||||||
|
|
||||||
Conversion functions
|
Conversion functions
|
||||||
~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
The ``django.utils.encoding`` module contains a few functions that are handy
|
The ``django.utils.encoding`` module contains a few functions that are handy
|
||||||
for converting back and forth between Unicode and bytestrings.
|
for converting back and forth between strings and bytestrings.
|
||||||
|
|
||||||
* ``smart_text(s, encoding='utf-8', strings_only=False, errors='strict')``
|
* ``smart_text(s, encoding='utf-8', strings_only=False, errors='strict')``
|
||||||
converts its input to a Unicode string. The ``encoding`` parameter
|
converts its input to a string. The ``encoding`` parameter
|
||||||
specifies the input encoding. (For example, Django uses this internally
|
specifies the input encoding. (For example, Django uses this internally
|
||||||
when processing form input data, which might not be UTF-8 encoded.) The
|
when processing form input data, which might not be UTF-8 encoded.) The
|
||||||
``strings_only`` parameter, if set to True, will result in Python
|
``strings_only`` parameter, if set to True, will result in Python
|
||||||
|
@ -126,7 +125,7 @@ for converting back and forth between Unicode and bytestrings.
|
||||||
cases. The difference is when the first argument is a :ref:`lazy
|
cases. The difference is when the first argument is a :ref:`lazy
|
||||||
translation <lazy-translations>` instance. While ``smart_text()``
|
translation <lazy-translations>` instance. While ``smart_text()``
|
||||||
preserves lazy translations, ``force_text()`` forces those objects to a
|
preserves lazy translations, ``force_text()`` forces those objects to a
|
||||||
Unicode string (causing the translation to occur). Normally, you'll want
|
string (causing the translation to occur). Normally, you'll want
|
||||||
to use ``smart_text()``. However, ``force_text()`` is useful in
|
to use ``smart_text()``. However, ``force_text()`` is useful in
|
||||||
template tags and filters that absolutely *must* have a string to work
|
template tags and filters that absolutely *must* have a string to work
|
||||||
with, not just something that can be converted to a string.
|
with, not just something that can be converted to a string.
|
||||||
|
@ -139,8 +138,8 @@ for converting back and forth between Unicode and bytestrings.
|
||||||
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 ``force_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 a string 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 a string.
|
||||||
|
|
||||||
.. _uri-and-iri-handling:
|
.. _uri-and-iri-handling:
|
||||||
|
|
||||||
|
@ -225,13 +224,13 @@ double-quoting problems.
|
||||||
Models
|
Models
|
||||||
======
|
======
|
||||||
|
|
||||||
Because all strings are returned from the database as Unicode strings, model
|
Because all strings are returned from the database as ``str`` objects, model
|
||||||
fields that are character based (CharField, TextField, URLField, etc.) will
|
fields that are character based (CharField, TextField, URLField, etc.) will
|
||||||
contain Unicode values when Django retrieves data from the database. This
|
contain Unicode values when Django retrieves data from the database. This
|
||||||
is *always* the case, even if the data could fit into an ASCII bytestring.
|
is *always* the case, even if the data could fit into an ASCII bytestring.
|
||||||
|
|
||||||
You can pass in bytestrings when creating a model or populating a field, and
|
You can pass in bytestrings when creating a model or populating a field, and
|
||||||
Django will convert it to Unicode when it needs to.
|
Django will convert it to strings when it needs to.
|
||||||
|
|
||||||
Taking care in ``get_absolute_url()``
|
Taking care in ``get_absolute_url()``
|
||||||
-------------------------------------
|
-------------------------------------
|
||||||
|
@ -263,7 +262,7 @@ non-ASCII characters would have been removed in quoting in the first line.)
|
||||||
The database API
|
The database API
|
||||||
================
|
================
|
||||||
|
|
||||||
You can pass either Unicode strings or UTF-8 bytestrings as arguments to
|
You can pass either strings or UTF-8 bytestrings as arguments to
|
||||||
``filter()`` methods and the like in the database API. The following two
|
``filter()`` methods and the like in the database API. The following two
|
||||||
querysets are identical::
|
querysets are identical::
|
||||||
|
|
||||||
|
@ -273,11 +272,12 @@ querysets are identical::
|
||||||
Templates
|
Templates
|
||||||
=========
|
=========
|
||||||
|
|
||||||
You can use either Unicode or bytestrings when creating templates manually::
|
You can use either strings or UTF-8 bytestrings when creating templates
|
||||||
|
manually::
|
||||||
|
|
||||||
from django.template import Template
|
from django.template import Template
|
||||||
t1 = Template(b'This is a bytestring template.')
|
t1 = Template(b'This is a bytestring template.')
|
||||||
t2 = Template('This is a Unicode template.')
|
t2 = Template('This is a string template.')
|
||||||
|
|
||||||
But the common case is to read templates from the filesystem, and this creates
|
But the common case is to read templates from the filesystem, and this creates
|
||||||
a slight complication: not all filesystems store their data encoded as UTF-8.
|
a slight complication: not all filesystems store their data encoded as UTF-8.
|
||||||
|
@ -294,13 +294,13 @@ Template tags and filters
|
||||||
|
|
||||||
A couple of tips to remember when writing your own template tags and filters:
|
A couple of tips to remember when writing your own template tags and filters:
|
||||||
|
|
||||||
* Always return Unicode strings from a template tag's ``render()`` method
|
* Always return strings from a template tag's ``render()`` method
|
||||||
and from template filters.
|
and from template filters.
|
||||||
|
|
||||||
* Use ``force_text()`` in preference to ``smart_text()`` in these
|
* Use ``force_text()`` in preference to ``smart_text()`` in these
|
||||||
places. Tag rendering and filter calls occur as the template is being
|
places. Tag rendering and filter calls occur as the template is being
|
||||||
rendered, so there is no advantage to postponing the conversion of lazy
|
rendered, so there is no advantage to postponing the conversion of lazy
|
||||||
translation objects into strings. It's easier to work solely with Unicode
|
translation objects into strings. It's easier to work solely with
|
||||||
strings at that point.
|
strings at that point.
|
||||||
|
|
||||||
.. _unicode-files:
|
.. _unicode-files:
|
||||||
|
|
|
@ -276,13 +276,13 @@ The functions defined in this module share the following properties:
|
||||||
|
|
||||||
This is an algorithm from section 3.2 of :rfc:`3987#section-3.2`.
|
This is an algorithm from section 3.2 of :rfc:`3987#section-3.2`.
|
||||||
|
|
||||||
Takes a URI in ASCII bytes and returns a unicode string containing the
|
Takes a URI in ASCII bytes and returns a string containing the encoded
|
||||||
encoded result.
|
result.
|
||||||
|
|
||||||
.. function:: filepath_to_uri(path)
|
.. function:: filepath_to_uri(path)
|
||||||
|
|
||||||
Convert a file system path to a URI portion that is suitable for inclusion
|
Convert a file system path to a URI portion that is suitable for inclusion
|
||||||
in a URL. The path is assumed to be either UTF-8 or unicode.
|
in a URL. The path is assumed to be either UTF-8 bytes or string.
|
||||||
|
|
||||||
This method will encode certain characters that would normally be
|
This method will encode certain characters that would normally be
|
||||||
recognized as special characters for URIs. Note that this method does not
|
recognized as special characters for URIs. Note that this method does not
|
||||||
|
@ -346,13 +346,13 @@ https://web.archive.org/web/20110718035220/http://diveintomark.org/archives/2004
|
||||||
Any extra keyword arguments you pass to ``__init__`` will be stored in
|
Any extra keyword arguments you pass to ``__init__`` will be stored in
|
||||||
``self.feed``.
|
``self.feed``.
|
||||||
|
|
||||||
All parameters should be Unicode objects, except ``categories``, which
|
All parameters should be strings, except ``categories``, which should
|
||||||
should be a sequence of Unicode objects.
|
be a sequence of strings.
|
||||||
|
|
||||||
.. method:: add_item(title, link, description, author_email=None, author_name=None, author_link=None, pubdate=None, comments=None, unique_id=None, categories=(), item_copyright=None, ttl=None, updateddate=None, enclosures=None, **kwargs)
|
.. method:: add_item(title, link, description, author_email=None, author_name=None, author_link=None, pubdate=None, comments=None, unique_id=None, categories=(), item_copyright=None, ttl=None, updateddate=None, enclosures=None, **kwargs)
|
||||||
|
|
||||||
Adds an item to the feed. All args are expected to be Python ``unicode``
|
Adds an item to the feed. All args are expected to be strings except
|
||||||
objects except ``pubdate`` and ``updateddate``, which are ``datetime.datetime``
|
``pubdate`` and ``updateddate``, which are ``datetime.datetime``
|
||||||
objects, and ``enclosures``, which is a list of ``Enclosure`` instances.
|
objects, and ``enclosures``, which is a list of ``Enclosure`` instances.
|
||||||
|
|
||||||
.. method:: num_items()
|
.. method:: num_items()
|
||||||
|
@ -802,7 +802,7 @@ appropriate entities.
|
||||||
.. function:: mark_safe(s)
|
.. function:: mark_safe(s)
|
||||||
|
|
||||||
Explicitly mark a string as safe for (HTML) output purposes. The returned
|
Explicitly mark a string as safe for (HTML) output purposes. The returned
|
||||||
object can be used everywhere a string or unicode object is appropriate.
|
object can be used everywhere a string is appropriate.
|
||||||
|
|
||||||
Can be called multiple times on a single string.
|
Can be called multiple times on a single string.
|
||||||
|
|
||||||
|
@ -1030,16 +1030,15 @@ For a complete discussion on the usage of the following see the
|
||||||
|
|
||||||
.. function:: gettext(message)
|
.. function:: gettext(message)
|
||||||
|
|
||||||
Translates ``message`` and returns it in a UTF-8 bytestring
|
Translates ``message`` and returns it in a UTF-8 bytestring.
|
||||||
|
|
||||||
.. function:: ugettext(message)
|
.. function:: ugettext(message)
|
||||||
|
|
||||||
Translates ``message`` and returns it in a unicode string
|
Translates ``message`` and returns it as a string.
|
||||||
|
|
||||||
.. function:: pgettext(context, message)
|
.. function:: pgettext(context, message)
|
||||||
|
|
||||||
Translates ``message`` given the ``context`` and returns
|
Translates ``message`` given the ``context`` and returns it as a string.
|
||||||
it in a unicode string.
|
|
||||||
|
|
||||||
For more information, see :ref:`contextual-markers`.
|
For more information, see :ref:`contextual-markers`.
|
||||||
|
|
||||||
|
@ -1067,12 +1066,12 @@ For a complete discussion on the usage of the following see the
|
||||||
.. function:: ungettext(singular, plural, number)
|
.. function:: ungettext(singular, plural, number)
|
||||||
|
|
||||||
Translates ``singular`` and ``plural`` and returns the appropriate string
|
Translates ``singular`` and ``plural`` and returns the appropriate string
|
||||||
based on ``number`` in a unicode string.
|
based on ``number`` as a string.
|
||||||
|
|
||||||
.. function:: npgettext(context, singular, plural, number)
|
.. function:: npgettext(context, singular, plural, number)
|
||||||
|
|
||||||
Translates ``singular`` and ``plural`` and returns the appropriate string
|
Translates ``singular`` and ``plural`` and returns the appropriate string
|
||||||
based on ``number`` and the ``context`` in a unicode string.
|
based on ``number`` and the ``context`` as a string.
|
||||||
|
|
||||||
.. function:: ngettext_lazy(singular, plural, number)
|
.. function:: ngettext_lazy(singular, plural, number)
|
||||||
.. function:: ungettext_lazy(singular, plural, number)
|
.. function:: ungettext_lazy(singular, plural, number)
|
||||||
|
|
|
@ -121,7 +121,7 @@ default, call the view ``django.views.defaults.permission_denied``.
|
||||||
This view loads and renders the template ``403.html`` in your root template
|
This view loads and renders the template ``403.html`` in your root template
|
||||||
directory, or if this file does not exist, instead serves the text
|
directory, or if this file does not exist, instead serves the text
|
||||||
"403 Forbidden", as per :rfc:`7231#section-6.5.3` (the HTTP 1.1 Specification).
|
"403 Forbidden", as per :rfc:`7231#section-6.5.3` (the HTTP 1.1 Specification).
|
||||||
The template context contains ``exception``, which is the unicode
|
The template context contains ``exception``, which is the string
|
||||||
representation of the exception that triggered the view.
|
representation of the exception that triggered the view.
|
||||||
|
|
||||||
``django.views.defaults.permission_denied`` is triggered by a
|
``django.views.defaults.permission_denied`` is triggered by a
|
||||||
|
|
|
@ -762,7 +762,7 @@ You can override most of these -- see `overriding predefined model methods`_,
|
||||||
below -- but there are a couple that you'll almost always want to define:
|
below -- but there are a couple that you'll almost always want to define:
|
||||||
|
|
||||||
:meth:`~Model.__str__`
|
:meth:`~Model.__str__`
|
||||||
A Python "magic method" that returns a unicode "representation" of any
|
A Python "magic method" that returns a string representation of any
|
||||||
object. This is what Python and Django will use whenever a model
|
object. This is what Python and Django will use whenever a model
|
||||||
instance needs to be coerced and displayed as a plain string. Most
|
instance needs to be coerced and displayed as a plain string. Most
|
||||||
notably, this happens when you display an object in an interactive
|
notably, this happens when you display an object in an interactive
|
||||||
|
|
|
@ -472,11 +472,6 @@ Setup
|
||||||
of local time. This shields you from subtle and unreproducible bugs around
|
of local time. This shields you from subtle and unreproducible bugs around
|
||||||
Daylight Saving Time (DST) transitions.
|
Daylight Saving Time (DST) transitions.
|
||||||
|
|
||||||
In this regard, time zones are comparable to ``unicode`` in Python. At first
|
|
||||||
it's hard. You get encoding and decoding errors. Then you learn the rules.
|
|
||||||
And some problems disappear -- you never get mangled output again when your
|
|
||||||
application receives non-ASCII input.
|
|
||||||
|
|
||||||
When you enable time zone support, you'll encounter some errors because
|
When you enable time zone support, you'll encounter some errors because
|
||||||
you're using naive datetimes where Django expects aware datetimes. Such
|
you're using naive datetimes where Django expects aware datetimes. Such
|
||||||
errors show up when running tests and they're easy to fix. You'll quickly
|
errors show up when running tests and they're easy to fix. You'll quickly
|
||||||
|
|
|
@ -57,12 +57,9 @@ as a shorter alias, ``_``, to save typing.
|
||||||
global namespace, as an alias for ``gettext()``. In Django, we have chosen
|
global namespace, as an alias for ``gettext()``. In Django, we have chosen
|
||||||
not to follow this practice, for a couple of reasons:
|
not to follow this practice, for a couple of reasons:
|
||||||
|
|
||||||
1. For international character set (Unicode) support,
|
1. Sometimes, you should use :func:`~django.utils.translation.ugettext_lazy`
|
||||||
:func:`~django.utils.translation.ugettext` is more useful than
|
as the default translation method for a particular file. Without ``_()``
|
||||||
``gettext()``. Sometimes, you should be using
|
in the global namespace, the developer has to think about which is the
|
||||||
:func:`~django.utils.translation.ugettext_lazy` as the default
|
|
||||||
translation method for a particular file. Without ``_()`` in the
|
|
||||||
global namespace, the developer has to think about which is the
|
|
||||||
most appropriate translation function.
|
most appropriate translation function.
|
||||||
|
|
||||||
2. The underscore character (``_``) is used to represent "the previous
|
2. The underscore character (``_``) is used to represent "the previous
|
||||||
|
@ -418,7 +415,7 @@ Working with lazy translation objects
|
||||||
-------------------------------------
|
-------------------------------------
|
||||||
|
|
||||||
The result of a ``ugettext_lazy()`` call can be used wherever you would use a
|
The result of a ``ugettext_lazy()`` call can be used wherever you would use a
|
||||||
unicode string (a :class:`str` object) in other Django code, but it may not
|
string (a :class:`str` object) in other Django code, but it may not
|
||||||
work with arbitrary Python code. For example, the following won't work because
|
work with arbitrary Python code. For example, the following won't work because
|
||||||
the `requests <https://pypi.python.org/pypi/requests/>`_ library doesn't handle
|
the `requests <https://pypi.python.org/pypi/requests/>`_ library doesn't handle
|
||||||
``ugettext_lazy`` objects::
|
``ugettext_lazy`` objects::
|
||||||
|
@ -434,14 +431,14 @@ strings before passing them to non-Django code::
|
||||||
If you try to use a ``ugettext_lazy()`` result where a bytestring (a
|
If you try to use a ``ugettext_lazy()`` result where a bytestring (a
|
||||||
:class:`bytes` object) is expected, things won't work as expected since a
|
:class:`bytes` object) is expected, things won't work as expected since a
|
||||||
``ugettext_lazy()`` object doesn't know how to convert itself to a bytestring.
|
``ugettext_lazy()`` object doesn't know how to convert itself to a bytestring.
|
||||||
You can't use a unicode string inside a bytestring, either, so this is
|
You can't use a string inside a bytestring, either, so this is consistent with
|
||||||
consistent with normal Python behavior. For example, putting a unicode proxy
|
normal Python behavior. For example, putting a string proxy into a string is
|
||||||
into a unicode string is fine::
|
fine::
|
||||||
|
|
||||||
"Hello %s" % ugettext_lazy("people")
|
"Hello %s" % ugettext_lazy("people")
|
||||||
|
|
||||||
But you can't insert a unicode object into a bytestring and nor can you insert
|
But you can't insert a string into a bytestring and nor can you insert
|
||||||
a unicode proxy there::
|
a string proxy there::
|
||||||
|
|
||||||
b"Hello %s" % ugettext_lazy("people")
|
b"Hello %s" % ugettext_lazy("people")
|
||||||
|
|
||||||
|
|
|
@ -653,7 +653,7 @@ for basic values, and doesn't specify import paths).
|
||||||
|
|
||||||
Django can serialize the following:
|
Django can serialize the following:
|
||||||
|
|
||||||
- ``int``, ``float``, ``bool``, ``str``, ``unicode``, ``bytes``, ``None``
|
- ``int``, ``float``, ``bool``, ``str``, ``bytes``, ``None``
|
||||||
- ``list``, ``set``, ``tuple``, ``dict``
|
- ``list``, ``set``, ``tuple``, ``dict``
|
||||||
- ``datetime.date``, ``datetime.time``, and ``datetime.datetime`` instances
|
- ``datetime.date``, ``datetime.time``, and ``datetime.datetime`` instances
|
||||||
(include those that are timezone-aware)
|
(include those that are timezone-aware)
|
||||||
|
|
|
@ -411,9 +411,7 @@ class LastExecutedQueryTest(TestCase):
|
||||||
self.assertIn(Reporter._meta.db_table, sql)
|
self.assertIn(Reporter._meta.db_table, sql)
|
||||||
|
|
||||||
def test_query_encoding(self):
|
def test_query_encoding(self):
|
||||||
"""
|
"""last_executed_query() returns a string."""
|
||||||
last_executed_query() returns an Unicode string
|
|
||||||
"""
|
|
||||||
data = RawData.objects.filter(raw_data=b'\x00\x46 \xFE').extra(select={'föö': 1})
|
data = RawData.objects.filter(raw_data=b'\x00\x46 \xFE').extra(select={'föö': 1})
|
||||||
sql, params = data.query.sql_with_params()
|
sql, params = data.query.sql_with_params()
|
||||||
cursor = data.query.get_compiler('default').execute_sql(CURSOR)
|
cursor = data.query.get_compiler('default').execute_sql(CURSOR)
|
||||||
|
|
|
@ -69,9 +69,8 @@ class DataTypesTestCase(TestCase):
|
||||||
self.assertEqual(0, Donut.objects.filter(consumed_at__year=2005).count())
|
self.assertEqual(0, Donut.objects.filter(consumed_at__year=2005).count())
|
||||||
self.assertEqual(0, Donut.objects.filter(consumed_at__year=2008).count())
|
self.assertEqual(0, Donut.objects.filter(consumed_at__year=2008).count())
|
||||||
|
|
||||||
def test_textfields_unicode(self):
|
def test_textfields_str(self):
|
||||||
"""Regression test for #10238: TextField values returned from the
|
"""TextField values returned from the database should be str."""
|
||||||
database should be unicode."""
|
|
||||||
d = Donut.objects.create(name='Jelly Donut', review='Outstanding')
|
d = Donut.objects.create(name='Jelly Donut', review='Outstanding')
|
||||||
newd = Donut.objects.get(id=d.id)
|
newd = Donut.objects.get(id=d.id)
|
||||||
self.assertIsInstance(newd.review, str)
|
self.assertIsInstance(newd.review, str)
|
||||||
|
|
|
@ -6,7 +6,7 @@ from .base import WidgetTest
|
||||||
|
|
||||||
class FakeFieldFile:
|
class FakeFieldFile:
|
||||||
"""
|
"""
|
||||||
Quacks like a FieldFile (has a .url and unicode representation), but
|
Quacks like a FieldFile (has a .url and string representation), but
|
||||||
doesn't require us to care about storages etc.
|
doesn't require us to care about storages etc.
|
||||||
"""
|
"""
|
||||||
url = 'something'
|
url = 'something'
|
||||||
|
|
|
@ -28,9 +28,7 @@ class TimeInputTest(WidgetTest):
|
||||||
))
|
))
|
||||||
|
|
||||||
def test_string(self):
|
def test_string(self):
|
||||||
"""
|
"""Initializing from a string value."""
|
||||||
We should be able to initialize from a unicode value.
|
|
||||||
"""
|
|
||||||
self.check_html(self.widget, 'time', '13:12:11', html=(
|
self.check_html(self.widget, 'time', '13:12:11', html=(
|
||||||
'<input type="text" name="time" value="13:12:11" />'
|
'<input type="text" name="time" value="13:12:11" />'
|
||||||
))
|
))
|
||||||
|
|
|
@ -280,7 +280,7 @@ class HttpResponseTests(unittest.TestCase):
|
||||||
def test_headers_type(self):
|
def test_headers_type(self):
|
||||||
r = HttpResponse()
|
r = HttpResponse()
|
||||||
|
|
||||||
# ASCII unicode or bytes values are converted to strings.
|
# ASCII strings or bytes values are converted to strings.
|
||||||
r['key'] = 'test'
|
r['key'] = 'test'
|
||||||
self.assertEqual(r['key'], 'test')
|
self.assertEqual(r['key'], 'test')
|
||||||
r['key'] = 'test'.encode('ascii')
|
r['key'] = 'test'.encode('ascii')
|
||||||
|
@ -296,7 +296,7 @@ class HttpResponseTests(unittest.TestCase):
|
||||||
self.assertEqual(r['key'], '=?utf-8?b?4oCg?=')
|
self.assertEqual(r['key'], '=?utf-8?b?4oCg?=')
|
||||||
self.assertIn(b'=?utf-8?b?4oCg?=', r.serialize_headers())
|
self.assertIn(b'=?utf-8?b?4oCg?=', r.serialize_headers())
|
||||||
|
|
||||||
# The response also converts unicode or bytes keys to strings, but requires
|
# The response also converts string or bytes keys to strings, but requires
|
||||||
# them to contain ASCII
|
# them to contain ASCII
|
||||||
r = HttpResponse()
|
r = HttpResponse()
|
||||||
del r['Content-Type']
|
del r['Content-Type']
|
||||||
|
@ -570,7 +570,7 @@ class StreamingHttpResponseTests(SimpleTestCase):
|
||||||
self.assertEqual(list(r), [b'abc', b'def'])
|
self.assertEqual(list(r), [b'abc', b'def'])
|
||||||
self.assertEqual(list(r), [])
|
self.assertEqual(list(r), [])
|
||||||
|
|
||||||
# iterating over Unicode strings still yields bytestring chunks.
|
# iterating over strings still yields bytestring chunks.
|
||||||
r.streaming_content = iter(['hello', 'café'])
|
r.streaming_content = iter(['hello', 'café'])
|
||||||
chunks = list(r)
|
chunks = list(r)
|
||||||
# '\xc3\xa9' == unichr(233).encode('utf-8')
|
# '\xc3\xa9' == unichr(233).encode('utf-8')
|
||||||
|
|
|
@ -22,5 +22,5 @@ class Issue(models.Model):
|
||||||
ordering = ('num',)
|
ordering = ('num',)
|
||||||
|
|
||||||
|
|
||||||
class UnicodeReferenceModel(models.Model):
|
class StringReferenceModel(models.Model):
|
||||||
others = models.ManyToManyField("UnicodeReferenceModel")
|
others = models.ManyToManyField('StringReferenceModel')
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
from django.db.models import Q
|
from django.db.models import Q
|
||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
|
|
||||||
from .models import Issue, UnicodeReferenceModel, User
|
from .models import Issue, StringReferenceModel, User
|
||||||
|
|
||||||
|
|
||||||
class RelatedObjectTests(TestCase):
|
class RelatedObjectTests(TestCase):
|
||||||
|
@ -84,11 +84,11 @@ class RelatedObjectTests(TestCase):
|
||||||
class RelatedObjectUnicodeTests(TestCase):
|
class RelatedObjectUnicodeTests(TestCase):
|
||||||
def test_m2m_with_unicode_reference(self):
|
def test_m2m_with_unicode_reference(self):
|
||||||
"""
|
"""
|
||||||
Regression test for #6045: references to other models can be unicode
|
Regression test for #6045: references to other models can be
|
||||||
strings, providing they are directly convertible to ASCII.
|
strings, providing they are directly convertible to ASCII.
|
||||||
"""
|
"""
|
||||||
m1 = UnicodeReferenceModel.objects.create()
|
m1 = StringReferenceModel.objects.create()
|
||||||
m2 = UnicodeReferenceModel.objects.create()
|
m2 = StringReferenceModel.objects.create()
|
||||||
m2.others.add(m1) # used to cause an error (see ticket #6045)
|
m2.others.add(m1) # used to cause an error (see ticket #6045)
|
||||||
m2.save()
|
m2.save()
|
||||||
list(m2.others.all()) # Force retrieval.
|
list(m2.others.all()) # Force retrieval.
|
||||||
|
|
|
@ -29,7 +29,7 @@ class Tag(models.Model):
|
||||||
|
|
||||||
class Article(models.Model):
|
class Article(models.Model):
|
||||||
headline = models.CharField(max_length=100)
|
headline = models.CharField(max_length=100)
|
||||||
# Assign a unicode string as name to make sure the intermediary model is
|
# Assign a string as name to make sure the intermediary model is
|
||||||
# correctly created. Refs #20207
|
# correctly created. Refs #20207
|
||||||
publications = models.ManyToManyField(Publication, name='publications')
|
publications = models.ManyToManyField(Publication, name='publications')
|
||||||
tags = models.ManyToManyField(Tag, related_name='tags')
|
tags = models.ManyToManyField(Tag, related_name='tags')
|
||||||
|
|
|
@ -28,9 +28,6 @@ class ManyToOneTests(TestCase):
|
||||||
# Article objects have access to their related Reporter objects.
|
# Article objects have access to their related Reporter objects.
|
||||||
r = self.a.reporter
|
r = self.a.reporter
|
||||||
self.assertEqual(r.id, self.r.id)
|
self.assertEqual(r.id, self.r.id)
|
||||||
# These are strings instead of unicode strings because that's what was used in
|
|
||||||
# the creation of this reporter (and we haven't refreshed the data from the
|
|
||||||
# database, which always returns unicode strings).
|
|
||||||
self.assertEqual((r.first_name, self.r.last_name), ('John', 'Smith'))
|
self.assertEqual((r.first_name, self.r.last_name), ('John', 'Smith'))
|
||||||
|
|
||||||
def test_create(self):
|
def test_create(self):
|
||||||
|
@ -200,7 +197,7 @@ class ManyToOneTests(TestCase):
|
||||||
where=["many_to_one_reporter.last_name='Smith'"]),
|
where=["many_to_one_reporter.last_name='Smith'"]),
|
||||||
["<Article: John's second story>", "<Article: This is a test>"]
|
["<Article: John's second story>", "<Article: This is a test>"]
|
||||||
)
|
)
|
||||||
# ... and should work fine with the unicode that comes out of forms.Form.cleaned_data
|
# ... and should work fine with the string that comes out of forms.Form.cleaned_data
|
||||||
self.assertQuerysetEqual(
|
self.assertQuerysetEqual(
|
||||||
(Article.objects
|
(Article.objects
|
||||||
.filter(reporter__first_name__exact='John')
|
.filter(reporter__first_name__exact='John')
|
||||||
|
|
|
@ -52,7 +52,7 @@ class Worker(models.Model):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
|
|
||||||
class BrokenUnicodeMethod(models.Model):
|
class BrokenStrMethod(models.Model):
|
||||||
name = models.CharField(max_length=7)
|
name = models.CharField(max_length=7)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
|
|
|
@ -8,7 +8,7 @@ from django.test import TestCase, skipUnlessDBFeature
|
||||||
from django.utils.timezone import get_fixed_timezone
|
from django.utils.timezone import get_fixed_timezone
|
||||||
|
|
||||||
from .models import (
|
from .models import (
|
||||||
Article, BrokenUnicodeMethod, Department, Event, Model1, Model2, Model3,
|
Article, BrokenStrMethod, Department, Event, Model1, Model2, Model3,
|
||||||
NonAutoPK, Party, Worker,
|
NonAutoPK, Party, Worker,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -187,9 +187,9 @@ class ModelTests(TestCase):
|
||||||
self.assertEqual(str(w), "Full-time")
|
self.assertEqual(str(w), "Full-time")
|
||||||
|
|
||||||
def test_broken_unicode(self):
|
def test_broken_unicode(self):
|
||||||
# Models with broken unicode methods should still have a printable repr
|
# Models with broken __str__() methods have a printable repr().
|
||||||
b = BrokenUnicodeMethod.objects.create(name="Jerry")
|
b = BrokenStrMethod.objects.create(name='Jerry')
|
||||||
self.assertEqual(repr(b), "<BrokenUnicodeMethod: [Bad Unicode data]>")
|
self.assertEqual(repr(b), '<BrokenStrMethod: [Bad Unicode data]>')
|
||||||
|
|
||||||
@skipUnlessDBFeature("supports_timezones")
|
@skipUnlessDBFeature("supports_timezones")
|
||||||
def test_timezones(self):
|
def test_timezones(self):
|
||||||
|
|
|
@ -553,9 +553,6 @@ class Queries1Tests(TestCase):
|
||||||
s.reverse()
|
s.reverse()
|
||||||
params.reverse()
|
params.reverse()
|
||||||
|
|
||||||
# This slightly odd comparison works around the fact that PostgreSQL will
|
|
||||||
# return 'one' and 'two' as strings, not Unicode objects. It's a side-effect of
|
|
||||||
# using constants here and not a real concern.
|
|
||||||
d = Item.objects.extra(select=OrderedDict(s), select_params=params).values('a', 'b')[0]
|
d = Item.objects.extra(select=OrderedDict(s), select_params=params).values('a', 'b')[0]
|
||||||
self.assertEqual(d, {'a': 'one', 'b': 'two'})
|
self.assertEqual(d, {'a': 'one', 'b': 'two'})
|
||||||
|
|
||||||
|
|
|
@ -69,7 +69,7 @@ class TestSigner(SimpleTestCase):
|
||||||
"dumps and loads be reversible for any JSON serializable object"
|
"dumps and loads be reversible for any JSON serializable object"
|
||||||
objects = [
|
objects = [
|
||||||
['a', 'list'],
|
['a', 'list'],
|
||||||
'a unicode string \u2019',
|
'a string \u2019',
|
||||||
{'a': 'dictionary'},
|
{'a': 'dictionary'},
|
||||||
]
|
]
|
||||||
for o in objects:
|
for o in objects:
|
||||||
|
|
|
@ -160,8 +160,7 @@ class FilterSyntaxTests(SimpleTestCase):
|
||||||
@setup({'filter-syntax18': r'{{ var }}'})
|
@setup({'filter-syntax18': r'{{ var }}'})
|
||||||
def test_filter_syntax18(self):
|
def test_filter_syntax18(self):
|
||||||
"""
|
"""
|
||||||
Make sure that any unicode strings are converted to bytestrings
|
Strings are converted to bytestrings in the final output.
|
||||||
in the final output.
|
|
||||||
"""
|
"""
|
||||||
output = self.engine.render_to_string('filter-syntax18', {'var': UTF8Class()})
|
output = self.engine.render_to_string('filter-syntax18', {'var': UTF8Class()})
|
||||||
self.assertEqual(output, '\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111')
|
self.assertEqual(output, '\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111')
|
||||||
|
|
|
@ -158,7 +158,7 @@ class FileSystemLoaderTests(SimpleTestCase):
|
||||||
with self.source_checker(['/dir1', '/dir2']) as check_sources:
|
with self.source_checker(['/dir1', '/dir2']) as check_sources:
|
||||||
# UTF-8 bytestrings are permitted.
|
# UTF-8 bytestrings are permitted.
|
||||||
check_sources(b'\xc3\x85ngstr\xc3\xb6m', ['/dir1/Ångström', '/dir2/Ångström'])
|
check_sources(b'\xc3\x85ngstr\xc3\xb6m', ['/dir1/Ångström', '/dir2/Ångström'])
|
||||||
# Unicode strings are permitted.
|
# Strings are permitted.
|
||||||
check_sources('Ångström', ['/dir1/Ångström', '/dir2/Ångström'])
|
check_sources('Ångström', ['/dir1/Ångström', '/dir2/Ångström'])
|
||||||
|
|
||||||
def test_utf8_bytestring(self):
|
def test_utf8_bytestring(self):
|
||||||
|
|
|
@ -7,7 +7,7 @@ from django.utils.safestring import SafeData
|
||||||
|
|
||||||
class UnicodeTests(TestCase):
|
class UnicodeTests(TestCase):
|
||||||
def test_template(self):
|
def test_template(self):
|
||||||
# Templates can be created from unicode strings.
|
# Templates can be created from strings.
|
||||||
engine = Engine()
|
engine = Engine()
|
||||||
t1 = engine.from_string('ŠĐĆŽćžšđ {{ var }}')
|
t1 = engine.from_string('ŠĐĆŽćžšđ {{ var }}')
|
||||||
# Templates can also be created from bytestrings. These are assumed to
|
# Templates can also be created from bytestrings. These are assumed to
|
||||||
|
@ -17,14 +17,14 @@ class UnicodeTests(TestCase):
|
||||||
with self.assertRaises(TemplateEncodingError):
|
with self.assertRaises(TemplateEncodingError):
|
||||||
engine.from_string(b'\x80\xc5\xc0')
|
engine.from_string(b'\x80\xc5\xc0')
|
||||||
|
|
||||||
# Contexts can be constructed from unicode or UTF-8 bytestrings.
|
# Contexts can be constructed from strings or UTF-8 bytestrings.
|
||||||
Context({b"var": b"foo"})
|
Context({b"var": b"foo"})
|
||||||
Context({"var": b"foo"})
|
Context({"var": b"foo"})
|
||||||
c3 = Context({b"var": "Đđ"})
|
c3 = Context({b"var": "Đđ"})
|
||||||
Context({"var": b"\xc4\x90\xc4\x91"})
|
Context({"var": b"\xc4\x90\xc4\x91"})
|
||||||
|
|
||||||
# Since both templates and all four contexts represent the same thing,
|
# Since both templates and all four contexts represent the same thing,
|
||||||
# they all render the same (and are returned as unicode objects and
|
# they all render the same (and are returned as strings and
|
||||||
# "safe" objects as well, for auto-escaping purposes).
|
# "safe" objects as well, for auto-escaping purposes).
|
||||||
self.assertEqual(t1.render(c3), t2.render(c3))
|
self.assertEqual(t1.render(c3), t2.render(c3))
|
||||||
self.assertIsInstance(t1.render(c3), str)
|
self.assertIsInstance(t1.render(c3), str)
|
||||||
|
|
|
@ -169,7 +169,7 @@ class UTF8Class:
|
||||||
return 'ŠĐĆŽćžšđ'
|
return 'ŠĐĆŽćžšđ'
|
||||||
|
|
||||||
|
|
||||||
# These two classes are used to test auto-escaping of unicode output.
|
# These two classes are used to test auto-escaping of string output.
|
||||||
class UnsafeClass:
|
class UnsafeClass:
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return 'you & me'
|
return 'you & me'
|
||||||
|
|
|
@ -1266,7 +1266,7 @@ class QueryStringTests(SimpleTestCase):
|
||||||
class UnicodePayloadTests(SimpleTestCase):
|
class UnicodePayloadTests(SimpleTestCase):
|
||||||
|
|
||||||
def test_simple_unicode_payload(self):
|
def test_simple_unicode_payload(self):
|
||||||
"A simple ASCII-only unicode JSON document can be POSTed"
|
"A simple ASCII-only JSON document can be POSTed"
|
||||||
# Regression test for #10571
|
# Regression test for #10571
|
||||||
json = '{"english": "mountain pass"}'
|
json = '{"english": "mountain pass"}'
|
||||||
response = self.client.post("/parse_unicode_json/", json, content_type="application/json")
|
response = self.client.post("/parse_unicode_json/", json, content_type="application/json")
|
||||||
|
|
Loading…
Reference in New Issue