1
0
mirror of https://github.com/django/django.git synced 2025-07-04 01:39:20 +00:00

unicode: Render templates as unicode objects and only convert them to

bytestrings as part of HttpRespnose and other output paths.


git-svn-id: http://code.djangoproject.com/svn/django/branches/unicode@5487 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Malcolm Tredinnick 2007-06-17 10:25:48 +00:00
parent 1bfcfe615c
commit 2126d41aba
8 changed files with 15 additions and 23 deletions

View File

@ -2,6 +2,7 @@ from django.http import HttpResponse, Http404
from django.template import loader from django.template import loader
from django.contrib.sites.models import Site from django.contrib.sites.models import Site
from django.core import urlresolvers from django.core import urlresolvers
from django.utils.encoding import smart_str
def index(request, sitemaps): def index(request, sitemaps):
current_site = Site.objects.get_current() current_site = Site.objects.get_current()
@ -26,5 +27,5 @@ def sitemap(request, sitemaps, section=None):
urls.extend(site().get_urls()) urls.extend(site().get_urls())
else: else:
urls.extend(site.get_urls()) urls.extend(site.get_urls())
xml = loader.render_to_string('sitemap.xml', {'urlset': urls}, encoding='utf-8') xml = smart_str(loader.render_to_string('sitemap.xml', {'urlset': urls}))
return HttpResponse(xml, mimetype='application/xml') return HttpResponse(xml, mimetype='application/xml')

View File

@ -271,9 +271,7 @@ class HttpResponse(object):
self.cookies[key]['max-age'] = 0 self.cookies[key]['max-age'] = 0
def _get_content(self): def _get_content(self):
content = ''.join(self._container) content = smart_str(''.join(self._container), self._charset)
if isinstance(content, unicode):
content = content.encode(self._charset)
return content return content
def _set_content(self, value): def _set_content(self, value):

View File

@ -60,7 +60,7 @@ from django.conf import settings
from django.template.context import Context, RequestContext, ContextPopException from django.template.context import Context, RequestContext, ContextPopException
from django.utils.functional import curry, Promise from django.utils.functional import curry, Promise
from django.utils.text import smart_split from django.utils.text import smart_split
from django.utils.encoding import smart_unicode, smart_str, force_unicode from django.utils.encoding import smart_unicode, force_unicode
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
__all__ = ('Template', 'Context', 'RequestContext', 'compile_string') __all__ = ('Template', 'Context', 'RequestContext', 'compile_string')
@ -176,9 +176,9 @@ class Template(object):
for subnode in node: for subnode in node:
yield subnode yield subnode
def render(self, context, encoding=None): def render(self, context):
"Display stage -- can be called many times" "Display stage -- can be called many times"
return self.nodelist.render(context, encoding) return self.nodelist.render(context)
def compile_string(template_string, origin): def compile_string(template_string, origin):
"Compiles template_string into NodeList ready for rendering" "Compiles template_string into NodeList ready for rendering"
@ -732,21 +732,14 @@ class Node(object):
return nodes return nodes
class NodeList(list): class NodeList(list):
# How invalid encoding sequences are handled. The default 'strict' is not def render(self, context):
# appropriate, because the framework is not in control of all the string
# data.
codec_errors = 'replace'
def render(self, context, encoding=None):
if encoding is None:
encoding = settings.DEFAULT_CHARSET
bits = [] bits = []
for node in self: for node in self:
if isinstance(node, Node): if isinstance(node, Node):
bits.append(self.render_node(node, context)) bits.append(self.render_node(node, context))
else: else:
bits.append(node) bits.append(node)
return ''.join([smart_str(b, encoding, errors=self.codec_errors) for b in bits]) return ''.join([force_unicode(b) for b in bits])
def get_nodes_by_type(self, nodetype): def get_nodes_by_type(self, nodetype):
"Return a list of all nodes of the given type" "Return a list of all nodes of the given type"

View File

@ -87,7 +87,7 @@ def get_template_from_string(source, origin=None, name=None):
""" """
return Template(source, origin, name) return Template(source, origin, name)
def render_to_string(template_name, dictionary=None, context_instance=None, encoding=None): def render_to_string(template_name, dictionary=None, context_instance=None):
""" """
Loads the given template_name and renders it with the given dictionary as Loads the given template_name and renders it with the given dictionary as
context. The template_name may be a string to load a single template using context. The template_name may be a string to load a single template using
@ -103,7 +103,7 @@ def render_to_string(template_name, dictionary=None, context_instance=None, enco
context_instance.update(dictionary) context_instance.update(dictionary)
else: else:
context_instance = Context(dictionary) context_instance = Context(dictionary)
return t.render(context_instance, encoding) return t.render(context_instance)
def select_template(template_name_list): def select_template(template_name_list):
"Given a list of template names, returns the first that can be loaded." "Given a list of template names, returns the first that can be loaded."

View File

@ -10,7 +10,7 @@ from django.template import Template
# the test database. # the test database.
TEST_DATABASE_PREFIX = 'test_' TEST_DATABASE_PREFIX = 'test_'
def instrumented_test_render(self, context, unused=None): def instrumented_test_render(self, context):
""" """
An instrumented Template render method, providing a signal An instrumented Template render method, providing a signal
that can be intercepted by the test system Client that can be intercepted by the test system Client

View File

@ -3358,7 +3358,7 @@ does not have help text, nothing will be output.
<input type="submit" /> <input type="submit" />
</form> </form>
>>> Template('{{ form.password1.help_text }}').render(Context({'form': UserRegistration(auto_id=False)})) >>> Template('{{ form.password1.help_text }}').render(Context({'form': UserRegistration(auto_id=False)}))
'' u''
The label_tag() method takes an optional attrs argument: a dictionary of HTML The label_tag() method takes an optional attrs argument: a dictionary of HTML
attributes to add to the <label> tag. attributes to add to the <label> tag.

View File

@ -223,7 +223,7 @@ class Templates(unittest.TestCase):
# Make sure that any unicode strings are converted to bytestrings # Make sure that any unicode strings are converted to bytestrings
# in the final output. # in the final output.
'filter-syntax18': (r'{{ var }}', {'var': UTF8Class()}, '\xc5\xa0\xc4\x90\xc4\x86\xc5\xbd\xc4\x87\xc5\xbe\xc5\xa1\xc4\x91'), 'filter-syntax18': (r'{{ var }}', {'var': UTF8Class()}, u'\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111'),
### COMMENT SYNTAX ######################################################## ### COMMENT SYNTAX ########################################################
'comment-syntax01': ("{# this is hidden #}hello", {}, "hello"), 'comment-syntax01': ("{# this is hidden #}hello", {}, "hello"),

View File

@ -24,10 +24,10 @@ Contexts can be constructed from unicode or UTF-8 bytestrings.
>>> c4 = Context({u'var': '\xc4\x90\xc4\x91'}) >>> c4 = Context({u'var': '\xc4\x90\xc4\x91'})
Since both templates and all four contexts represent the same thing, they all Since both templates and all four contexts represent the same thing, they all
render the same (and are returned as bytestrings). render the same (and are returned as unicode objects).
>>> t1.render(c3) == t2.render(c3) >>> t1.render(c3) == t2.render(c3)
True True
>>> type(t1.render(c3)) >>> type(t1.render(c3))
<type 'str'> <type 'unicode'>
""" """