Django

Code

Changeset 5482

Show
Ignore:
Timestamp:
06/17/07 02:11:37 (1 year ago)
Author:
mtredinnick
Message:

Fixed #4565 -- Changed template rendering to use iterators, rather than
creating large strings, as much as possible. This is all backwards compatible.
Thanks, Brian Harring.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/trunk/django/contrib/admin/templatetags/adminapplist.py

    r4265 r5482  
    88        self.varname = varname 
    99 
    10     def render(self, context): 
     10    def iter_render(self, context): 
    1111        from django.db import models 
    1212        from django.utils.text import capfirst 
     
    5555                    }) 
    5656        context[self.varname] = app_list 
    57         return '' 
     57        return () 
    5858 
    5959def get_admin_app_list(parser, token): 
  • django/trunk/django/contrib/admin/templatetags/admin_modify.py

    r5091 r5482  
    9595    get_nodelist = classmethod(get_nodelist) 
    9696 
    97     def render(self, context): 
     97    def iter_render(self, context): 
    9898        bound_field = template.resolve_variable(self.bound_field_var, context) 
    9999 
     
    101101        context['bound_field'] = bound_field 
    102102 
    103         output = self.get_nodelist(bound_field.field.__class__).render(context) 
     103        for chunk in self.get_nodelist(bound_field.field.__class__).iter_render(context): 
     104            yield chunk 
    104105        context.pop() 
    105         return output 
    106106 
    107107class FieldWrapper(object): 
     
    158158        self.rel_var = rel_var 
    159159 
    160     def render(self, context): 
     160    def iter_render(self, context): 
    161161        relation = template.resolve_variable(self.rel_var, context) 
    162162        context.push() 
     
    170170        bound_related_object = relation.bind(context['form'], original, bound_related_object_class) 
    171171        context['bound_related_object'] = bound_related_object 
    172         t = loader.get_template(bound_related_object.template_name()) 
    173         output = t.render(context) 
     172        for chunk in loader.get_template(bound_related_object.template_name()).iter_render(context): 
     173            yield chunk 
    174174        context.pop() 
    175         return output 
    176175 
    177176def output_all(form_fields): 
  • django/trunk/django/contrib/admin/templatetags/log.py

    r5170 r5482  
    1111        return "<GetAdminLog Node>" 
    1212 
    13     def render(self, context): 
     13    def iter_render(self, context): 
    1414        if self.user is None: 
    1515            context[self.varname] = LogEntry.objects.all().select_related()[:self.limit] 
     
    1818                self.user = context[self.user].id 
    1919            context[self.varname] = LogEntry.objects.filter(user__id__exact=self.user).select_related()[:self.limit] 
    20         return '' 
     20        return () 
    2121 
    2222class DoGetAdminLog: 
  • django/trunk/django/contrib/comments/templatetags/comments.py

    r5091 r5482  
    2525        self.is_public = is_public 
    2626 
    27     def render(self, context): 
     27    def iter_render(self, context): 
    2828        from django.conf import settings 
    2929        from django.utils.text import normalize_newlines 
     
    3434                self.obj_id = template.resolve_variable(self.obj_id_lookup_var, context) 
    3535            except template.VariableDoesNotExist: 
    36                 return '' 
     36                return 
    3737            # Validate that this object ID is valid for this content-type. 
    3838            # We only have to do this validation if obj_id_lookup_var is provided, 
     
    6868            context['logout_url'] = settings.LOGOUT_URL 
    6969            default_form = loader.get_template(COMMENT_FORM) 
    70         output = default_form.render(context) 
     70        for chunk in default_form.iter_render(context): 
     71            yield chunk 
    7172        context.pop() 
    72         return output 
    7373 
    7474class CommentCountNode(template.Node): 
     
    7878        self.var_name, self.free = var_name, free 
    7979 
    80     def render(self, context): 
     80    def iter_render(self, context): 
    8181        from django.conf import settings 
    8282        manager = self.free and FreeComment.objects or Comment.objects 
     
    8787            content_type__model__exact=self.module, site__id__exact=settings.SITE_ID).count() 
    8888        context[self.var_name] = comment_count 
    89         return '' 
     89        return () 
    9090 
    9191class CommentListNode(template.Node): 
     
    9797        self.extra_kwargs = extra_kwargs or {} 
    9898 
    99     def render(self, context): 
     99    def iter_render(self, context): 
    100100        from django.conf import settings 
    101101        get_list_function = self.free and FreeComment.objects.filter or Comment.objects.get_list_with_karma 
     
    104104                self.obj_id = template.resolve_variable(self.context_var_name, context) 
    105105            except template.VariableDoesNotExist: 
    106                 return '' 
     106                return () 
    107107        kwargs = { 
    108108            'object_id__exact': self.obj_id, 
     
    128128 
    129129        context[self.var_name] = comment_list 
    130         return '' 
     130        return () 
    131131 
    132132class DoCommentForm: 
  • django/trunk/django/core/servers/basehttp.py

    r5091 r5482  
    310310        if not self.result_is_file() and not self.sendfile(): 
    311311            for data in self.result: 
    312                 self.write(data
     312                self.write(data, False
    313313            self.finish_content() 
    314314        self.close() 
     
    378378            self._write('Status: %s\r\n' % self.status) 
    379379 
    380     def write(self, data): 
     380    def write(self, data, flush=True): 
    381381        """'write()' callable as specified by PEP 333""" 
    382382 
     
    395395        # XXX check Content-Length and truncate if too many bytes written? 
    396396        self._write(data) 
    397         self._flush() 
     397        if flush: 
     398            self._flush() 
    398399 
    399400    def sendfile(self): 
     
    422423            self.headers['Content-Length'] = "0" 
    423424            self.send_headers() 
    424         else: 
    425             pass # XXX check if content-length was too short? 
    426425 
    427426    def close(self): 
  • django/trunk/django/http/__init__.py

    r5289 r5482  
    223223        if isinstance(content, unicode): 
    224224            content = content.encode(self._charset) 
     225 
     226        # If self._container was an iterator, we have just exhausted it, so we 
     227        # need to save the results for anything else that needs access 
     228        if not self._is_string: 
     229            self._container = [content] 
     230            self._is_string = True 
    225231        return content 
    226232 
     
    232238 
    233239    def __iter__(self): 
    234         self._iterator = self._container.__iter__() 
    235         return self 
    236  
    237     def next(self): 
    238         chunk = self._iterator.next() 
    239         if isinstance(chunk, unicode): 
    240             chunk = chunk.encode(self._charset) 
    241         return chunk 
     240        for chunk in self._container: 
     241            if isinstance(chunk, unicode): 
     242                chunk = chunk.encode(self._charset) 
     243            yield chunk 
    242244 
    243245    def close(self): 
  • django/trunk/django/oldforms/__init__.py

    r5398 r5482  
    309309        return data 
    310310    html2python = staticmethod(html2python) 
     311 
     312    def iter_render(self, data): 
     313        # this even needed? 
     314        return (self.render(data),) 
    311315 
    312316    def render(self, data): 
  • django/trunk/django/shortcuts/__init__.py

    r4756 r5482  
    88 
    99def render_to_response(*args, **kwargs): 
    10     return HttpResponse(loader.render_to_string(*args, **kwargs)) 
     10    return HttpResponse(loader.render_to_iter(*args, **kwargs)) 
    1111load_and_render = render_to_response # For backwards compatibility. 
    1212 
  • django/trunk/django/template/defaulttags.py

    r5454 r5482  
    1515            yield data[index] 
    1616 
    17  
    1817register = Library() 
    1918 
    2019class CommentNode(Node): 
    21     def render(self, context): 
    22         return '' 
     20    def iter_render(self, context): 
     21        return () 
    2322 
    2423class CycleNode(Node): 
     
    2928        self.variable_name = variable_name 
    3029 
     30    def iter_render(self, context): 
     31        return (self.render(context),) 
     32 
    3133    def render(self, context): 
    3234        self.counter += 1 
     
    3739 
    3840class DebugNode(Node): 
    39     def render(self, context): 
     41    def iter_render(self, context): 
    4042        from pprint import pformat 
    41         output = [pformat(val) for val in context] 
    42         output.append('\n\n'
    43         output.append(pformat(sys.modules)) 
    44         return ''.join(output
     43        for val in context: 
     44            yield pformat(val
     45        yield "\n\n" 
     46        yield pformat(sys.modules
    4547 
    4648class FilterNode(Node): 
     
    4850        self.filter_expr, self.nodelist = filter_expr, nodelist 
    4951 
    50     def render(self, context): 
     52    def iter_render(self, context): 
    5153        output = self.nodelist.render(context) 
    5254        # apply filters 
     
    5456        filtered = self.filter_expr.resolve(context) 
    5557        context.pop() 
    56         return filtered 
     58        return (filtered,) 
    5759 
    5860class FirstOfNode(Node): 
    5961    def __init__(self, vars): 
    6062        self.vars = vars 
     63 
     64    def iter_render(self, context): 
     65        return (self.render(context),) 
    6166 
    6267    def render(self, context): 
     
    95100        return nodes 
    96101 
    97     def render(self, context): 
    98         nodelist = NodeList() 
     102    def iter_render(self, context): 
    99103        if 'forloop' in context: 
    100104            parentloop = context['forloop'] 
     
    104108        try: 
    105109            values = self.sequence.resolve(context, True) 
     110            if values is None: 
     111                values = () 
     112            elif not hasattr(values, '__len__'): 
     113                values = list(values) 
    106114        except VariableDoesNotExist: 
    107             values = [] 
    108         if values is None: 
    109             values = [] 
    110         if not hasattr(values, '__len__'): 
    111             values = list(values) 
     115            values = () 
    112116        len_values = len(values) 
    113117        if self.reversed: 
     
    128132            } 
    129133            if unpack: 
    130                 # If there are multiple loop variables, unpack the item into them. 
     134                # If there are multiple loop variables, unpack the item into 
     135                # them. 
    131136                context.update(dict(zip(self.loopvars, item))) 
    132137            else: 
    133138                context[self.loopvars[0]] = item 
     139 
     140            # We inline this to avoid the overhead since ForNode is pretty 
     141            # common. 
    134142            for node in self.nodelist_loop: 
    135                 nodelist.append(node.render(context)) 
     143                for chunk in node.iter_render(context): 
     144                    yield chunk 
    136145            if unpack: 
    137146                # The loop variables were pushed on to the context so pop them 
     
    142151                context.pop() 
    143152        context.pop() 
    144         return nodelist.render(context) 
    145153 
    146154class IfChangedNode(Node): 
     
    150158        self._varlist = varlist 
    151159 
    152     def render(self, context): 
     160    def iter_render(self, context): 
    153161        if 'forloop' in context and context['forloop']['first']: 
    154162            self._last_seen = None 
     
    168176            context.push() 
    169177            context['ifchanged'] = {'firstloop': firstloop} 
    170             content = self.nodelist.render(context) 
     178            for chunk in self.nodelist.iter_render(context): 
     179                yield chunk 
    171180            context.pop() 
    172             return content 
    173         else: 
    174             return '' 
    175181 
    176182class IfEqualNode(Node): 
     
    183189        return "<IfEqualNode>" 
    184190 
    185     def render(self, context): 
     191    def iter_render(self, context): 
    186192        try: 
    187193            val1 = resolve_variable(self.var1, context) 
     
    193199            val2 = None 
    194200        if (self.negate and val1 != val2) or (not self.negate and val1 == val2): 
    195             return self.nodelist_true.render(context) 
    196         return self.nodelist_false.render(context) 
     201            return self.nodelist_true.iter_render(context) 
     202        return self.nodelist_false.iter_render(context) 
    197203 
    198204class IfNode(Node): 
     
    219225        return nodes 
    220226 
    221     def render(self, context): 
     227    def iter_render(self, context): 
    222228        if self.link_type == IfNode.LinkTypes.or_: 
    223229            for ifnot, bool_expr in self.bool_exprs: 
     
    227233                    value = None 
    228234                if (value and not ifnot) or (ifnot and not value): 
    229                     return self.nodelist_true.render(context) 
    230             return self.nodelist_false.render(context) 
     235                    return self.nodelist_true.iter_render(context) 
     236            return self.nodelist_false.iter_render(context) 
    231237        else: 
    232238            for ifnot, bool_expr in self.bool_exprs: 
     
    236242                    value = None 
    237243                if not ((value and not ifnot) or (ifnot and not value)): 
    238                     return self.nodelist_false.render(context) 
    239             return self.nodelist_true.render(context) 
     244                    return self.nodelist_false.iter_render(context) 
     245            return self.nodelist_true.iter_render(context) 
    240246 
    241247    class LinkTypes: 
     
    248254        self.var_name = var_name 
    249255 
    250     def render(self, context): 
     256    def iter_render(self, context): 
    251257        obj_list = self.target.resolve(context, True) 
    252258        if obj_list == None: # target_var wasn't found in context; fail silently 
    253259            context[self.var_name] = [] 
    254             return '' 
     260            return () 
    255261        output = [] # list of dictionaries in the format {'grouper': 'key', 'list': [list of contents]} 
    256262        for obj in obj_list: 
     
    262268                output.append({'grouper': grouper, 'list': [obj]}) 
    263269        context[self.var_name] = output 
    264         return '' 
     270        return () 
    265271 
    266272def include_is_allowed(filepath): 
     
    274280        self.filepath, self.parsed = filepath, parsed 
    275281 
    276     def render(self, context): 
     282    def iter_render(self, context): 
    277283        if not include_is_allowed(self.filepath): 
    278284            if settings.DEBUG: 
    279                 return "[Didn't have permission to include file]" 
     285                return ("[Didn't have permission to include file]",) 
    280286            else: 
    281287                return '' # Fail silently for invalid includes. 
     
    288294        if self.parsed: 
    289295            try: 
    290                 t = Template(output, name=self.filepath) 
    291                 return t.render(context) 
     296                return Template(output, name=self.filepath).iter_render(context) 
    292297            except TemplateSyntaxError, e: 
    293298                if settings.DEBUG: 
     
    295300                else: 
    296301                    return '' # Fail silently for invalid included templates. 
    297         return output 
     302        return (output,) 
    298303 
    299304class LoadNode(Node): 
    300     def render(self, context): 
    301         return '' 
     305    def iter_render(self, context): 
     306        return () 
    302307 
    303308class NowNode(Node): 
    304309    def __init__(self, format_string): 
    305310        self.format_string = format_string 
     311 
     312    def iter_render(self, context): 
     313        return (self.render(context),) 
    306314 
    307315    def render(self, context): 
     
    333341        self.tagtype = tagtype 
    334342 
     343    def iter_render(self, context): 
     344        return (self.render(context),) 
     345 
    335346    def render(self, context): 
    336347        return self.mapping.get(self.tagtype, '') 
     
    342353        self.kwargs = kwargs 
    343354 
    344     def render(self, context): 
     355    def iter_render(self, context): 
    345356        from django.core.urlresolvers import reverse, NoReverseMatch 
    346357        args = [arg.resolve(context) for arg in self.args] 
    347358        kwargs = dict([(k, v.resolve(context)) for k, v in self.kwargs.items()]) 
    348359        try: 
    349             return reverse(self.view_name, args=args, kwargs=kwargs
     360            return (reverse(self.view_name, args=args, kwargs=kwargs),
    350361        except NoReverseMatch: 
    351362            try: 
     
    353364                return reverse(project_name + '.' + self.view_name, args=args, kwargs=kwargs) 
    354365            except NoReverseMatch: 
    355                 return '' 
     366                return () 
    356367 
    357368class WidthRatioNode(Node): 
     
    360371        self.max_expr = max_expr 
    361372        self.max_width = max_width 
     373 
     374    def iter_render(self, context): 
     375        return (self.render(context),) 
    362376 
    363377    def render(self, context): 
     
    384398        return "<WithNode>" 
    385399 
    386     def render(self, context): 
     400    def iter_render(self, context): 
    387401        val = self.var.resolve(context) 
    388402        context.push() 
    389403        context[self.name] = val 
    390         output = self.nodelist.render(context) 
     404        for chunk in self.nodelist.iter_render(context): 
     405            yield chunk 
    391406        context.pop() 
    392         return output 
    393407 
    394408#@register.tag 
  • django/trunk/django/template/__init__.py

    r5333 r5482  
    5656""" 
    5757import re 
     58import types 
    5859from inspect import getargspec 
    5960from django.conf import settings 
     
    168169                yield subnode 
    169170 
     171    def iter_render(self, context): 
     172        "Display stage -- can be called many times" 
     173        return self.nodelist.iter_render(context) 
     174 
    170175    def render(self, context): 
    171         "Display stage -- can be called many times" 
    172         return self.nodelist.render(context) 
     176        return ''.join(self.iter_render(context)) 
    173177 
    174178def compile_string(template_string, origin): 
     
    699703    return current 
    700704 
     705class NodeBase(type): 
     706    def __new__(cls, name, bases, attrs): 
     707        """ 
     708        Ensures that either a 'render' or 'render_iter' method is defined on 
     709        any Node sub-class. This avoids potential infinite loops at runtime. 
     710        """ 
     711        if not (isinstance(attrs.get('render'), types.FunctionType) or 
     712                isinstance(attrs.get('iter_render'), types.FunctionType)): 
     713            raise TypeError('Unable to create Node subclass without either "render" or "iter_render" method.') 
     714        return type.__new__(cls, name, bases, attrs) 
     715 
    701716class Node(object): 
     717    __metaclass__ = NodeBase 
     718 
     719    def iter_render(self, context): 
     720        return (self.render(context),) 
     721 
    702722    def render(self, context): 
    703723        "Return the node rendered as a string" 
    704         pass 
     724        return ''.join(self.iter_render(context)) 
    705725 
    706726    def __iter__(self): 
     
    718738class NodeList(list): 
    719739    def render(self, context): 
    720         bits = [] 
     740        return ''.join(self.iter_render(context)) 
     741 
     742    def iter_render(self, context): 
    721743        for node in self: 
    722             if isinstance(node, Node): 
    723                 bits.append(self.render_node(node, context)) 
    724             else: 
    725                 bits.append(node) 
    726         return ''.join(bits) 
     744            for chunk in node.iter_render(context): 
     745                yield chunk 
    727746 
    728747    def get_nodes_by_type(self, nodetype): 
     
    733752        return nodes 
    734753 
    735     def render_node(self, node, context): 
    736         return(node.render(context)) 
    737754 
    738755class DebugNodeList(NodeList): 
    739     def render_node(self, node, context): 
    740         try: 
    741             result = node.render(context) 
    742         except TemplateSyntaxError, e: 
    743             if not hasattr(e, 'source'): 
    744                 e.source = node.source 
    745             raise 
    746         except Exception, e: 
    747             from sys import exc_info 
    748             wrapped = TemplateSyntaxError('Caught an exception while rendering: %s' % e) 
    749             wrapped.source = node.source 
    750             wrapped.exc_info = exc_info() 
    751             raise wrapped 
    752         return result 
     756    def iter_render(self, context): 
     757        for node in self: 
     758            if not isinstance(node, Node): 
     759                yield node 
     760                continue 
     761            try: 
     762                for chunk in node.iter_render(context): 
     763                    yield chunk 
     764            except TemplateSyntaxError, e: 
     765                if not hasattr(e, 'source'): 
     766                    e.source = node.source 
     767                raise 
     768            except Exception, e: 
     769                from sys import exc_info 
     770                wrapped = TemplateSyntaxError('Caught an exception while rendering: %s' % e) 
     771                wrapped.source = node.source 
     772                wrapped.exc_info = exc_info() 
     773                raise wrapped 
    753774 
    754775class TextNode(Node): 
     
    758779    def __repr__(self): 
    759780        return "<Text Node: '%s'>" % self.s[:25] 
     781 
     782    def iter_render(self, context): 
     783        return (self.s,) 
    760784 
    761785    def render(self, context): 
     
    781805        else: 
    782806            return output 
     807 
     808    def iter_render(self, context): 
     809        return (self.render(context),) 
    783810 
    784811    def render(self, context): 
     
    870897                self.vars_to_resolve = vars_to_resolve 
    871898 
     899            #def iter_render(self, context): 
     900            #    return (self.render(context),) 
     901 
    872902            def render(self, context): 
    873903                resolved_vars = [resolve_variable(var, context) for var in self.vars_to_resolve] 
     
    892922                    self.vars_to_resolve = vars_to_resolve 
    893923 
    894                 def render(self, context): 
     924                def iter_render(self, context): 
    895925                    resolved_vars = [resolve_variable(var, context) for var in self.vars_to_resolve] 
    896926                    if takes_context: 
     
    908938                            t = get_template(file_name) 
    909939                        self.nodelist = t.nodelist 
    910                     return self.nodelist.render(context_class(dict)) 
     940                    return self.nodelist.iter_render(context_class(dict)) 
    911941 
    912942            compile_func = curry(generic_tag_compiler, params, defaults, getattr(func, "_decorated_function", func).__name__, InclusionNode) 
  • django/trunk/django/template/loader.py

    r4265 r5482  
    8888    return Template(source, origin, name) 
    8989 
    90 def render_to_string(template_name, dictionary=None, context_instance=None): 
     90def _render_setup(template_name, dictionary=None, context_instance=None): 
    9191    """ 
    92     Loads the given template_name and renders it with the given dictionary as 
    93     context. The template_name may be a string to load a single template using 
    94     get_template, or it may be a tuple to use select_template to find one of 
    95     the templates in the list. Returns a string. 
     92    Common setup code for render_to_string and render_to_iter. 
    9693    """ 
    97     dictionary = dictionary or {} 
     94    if dictionary is None: 
     95        dictionary = {} 
    9896    if isinstance(template_name, (list, tuple)): 
    9997        t = select_template(template_name) 
     
    104102    else: 
    105103        context_instance = Context(dictionary) 
    106     return t.render(context_instance) 
     104    return t, context_instance 
     105 
     106def render_to_string(template_name, dictionary=None, context_instance=None): 
     107    """ 
     108    Loads the given template_name and renders it with the given dictionary as 
     109    context. The template_name may be a string to load a single template using 
     110    get_template, or it may be a tuple to use select_template to find one of 
     111    the templates in the list. Returns a string. 
     112    """ 
     113    t, c = _render_setup(template_name, dictionary=dictionary, context_instance=context_instance) 
     114    return t.render(c) 
     115 
     116def render_to_iter(template_name, dictionary=None, context_instance=None): 
     117    """ 
     118    Loads the given template_name and renders it with the given dictionary as 
     119    context. The template_name may be a string to load a single template using 
     120    get_template, or it may be a tuple to use select_template to find one of 
     121    the templates in the list. Returns a string. 
     122    """ 
     123    t, c = _render_setup(template_name, dictionary=dictionary, context_instance=context_instance) 
     124    return t.iter_render(c) 
     125 
    107126 
    108127def select_template(template_name_list): 
  • django/trunk/django/template/loader_tags.py

    r4492 r5482  
    1616        return "<Block Node: %s. Contents: %r>" % (self.name, self.nodelist) 
    1717 
    18     def render(self, context): 
     18    def iter_render(self, context): 
    1919        context.push() 
    2020        # Save context in case of block.super(). 
    2121        self.context = context 
    2222        context['block'] = self 
    23         result = self.nodelist.render(context) 
     23        for chunk in self.nodelist.iter_render(context): 
     24            yield chunk 
    2425        context.pop() 
    25         return result 
    2626 
    2727    def super(self): 
     
    6060            return get_template_from_string(source, origin, parent) 
    6161 
    62     def render(self, context): 
     62    def iter_render(self, context): 
    6363        compiled_parent = self.get_parent(context) 
    6464        parent_is_child = isinstance(compiled_parent.nodelist[0], ExtendsNode) 
     
    8080                parent_block.add_parent(parent_block.nodelist) 
    8181                parent_block.nodelist = block_node.nodelist 
    82         return compiled_parent.render(context) 
     82        return compiled_parent.iter_render(context) 
    8383 
    8484class ConstantIncludeNode(Node): 
     
    9292            self.template = None 
    9393 
    94     def render(self, context): 
     94    def iter_render(self, context): 
    9595        if self.template: 
    96             return self.template.render(context) 
    97         else: 
    98             return '' 
     96            return self.template.iter_render(context) 
     97        return () 
    9998 
    10099class IncludeNode(Node): 
     
    102101        self.template_name = template_name 
    103102 
    104     def render(self, context): 
     103    def iter_render(self, context): 
    105104        try: 
    106105            template_name = resolve_variable(self.template_name, context) 
    107106            t = get_template(template_name) 
    108             return t.render(context) 
     107            return t.iter_render(context) 
    109108        except TemplateSyntaxError, e: 
    110109            if settings.TEMPLATE_DEBUG: 
    111110                raise 
    112             return '' 
     111            return () 
    113112        except: 
    114             return '' # Fail silently for invalid included templates. 
     113            return () # Fail silently for invalid included templates. 
    115114 
    116115def do_block(parser, token): 
  • django/trunk/django/test/utils.py

    r5380 r5482  
    1212 
    1313def instrumented_test_render(self, context): 
    14     """An instrumented Template render method, providing a signal  
    15     that can be intercepted by the test system Client 
    16      
     14    """ 
     15    An instrumented Template render method, providing a signal that can be 
     16    intercepted by the test system Client. 
    1717    """ 
    1818    dispatcher.send(signal=signals.template_rendered, sender=self, template=self, context=context) 
    1919    return self.nodelist.render(context) 
     20 
     21def instrumented_test_iter_render(self, context): 
     22    """ 
     23    An instrumented Template iter_render method, providing a signal that can be 
     24    intercepted by the test system Client. 
     25    """ 
     26    for chunk in self.nodelist.iter_render(context): 
     27        yield chunk 
     28    dispatcher.send(signal=signals.template_rendered, sender=self, template=self, context=context) 
    2029     
    2130class TestSMTPConnection(object): 
     
    4554    """ 
    4655    Template.original_render = Template.render 
     56    Template.original_iter_render = Template.iter_render 
    4757    Template.render = instrumented_test_render 
     58    Template.iter_render = instrumented_test_render 
    4859     
    4960    mail.original_SMTPConnection = mail.SMTPConnection 
     
    6071    """ 
    6172    Template.render = Template.original_render 
    62     del Template.original_render 
     73    Template.iter_render = Template.original_iter_render 
     74    del Template.original_render, Template.original_iter_render 
    6375     
    6476    mail.SMTPConnection = mail.original_SMTPConnection 
  • django/trunk/django/views/debug.py

    r5456 r5482  
    138138        'loader_debug_info': loader_debug_info, 
    139139    }) 
    140     return HttpResponseServerError(t.render(c), mimetype='text/html') 
     140    return HttpResponseServerError(t.iter_render(c), mimetype='text/html') 
    141141 
    142142def technical_404_response(request, exception): 
     
    161161        'settings': get_safe_settings(), 
    162162    }) 
    163     return HttpResponseNotFound(t.render(c), mimetype='text/html') 
     163    return HttpResponseNotFound(t.iter_render(c), mimetype='text/html') 
    164164 
    165165def empty_urlconf(request): 
     
    169169        'project_name': settings.SETTINGS_MODULE.split('.')[0] 
    170170    }) 
    171     return HttpResponseNotFound(t.render(c), mimetype='text/html') 
     171    return HttpResponseNotFound(t.iter_render(c), mimetype='text/html') 
    172172 
    173173def _get_lines_from_file(filename, lineno, context_lines, loader=None, module_name=None): 
  • django/trunk/django/views/defaults.py

    r4612 r5482  
    7777    """ 
    7878    t = loader.get_template(template_name) # You need to create a 404.html template. 
    79     return http.HttpResponseNotFound(t.render(RequestContext(request, {'request_path': request.path}))) 
     79    return http.HttpResponseNotFound(t.iter_render(RequestContext(request, {'request_path': request.path}))) 
    8080 
    8181def server_error(request, template_name='500.html'): 
     
    8787    """ 
    8888    t = loader.get_template(template_name) # You need to create a 500.html template. 
    89     return http.HttpResponseServerError(t.render(Context({}))) 
     89    return http.HttpResponseServerError(t.iter_render(Context({})))