Ticket #12816: t12815-rc1.diff

File t12815-rc1.diff, 81.2 KB (added by Russell Keith-Magee, 14 years ago)

RC1 for TemplateResponse and render() shortcut

  • django/contrib/messages/middleware.py

    diff -r 78ad3faa689b django/contrib/messages/middleware.py
    a b  
    11from django.conf import settings
    22from django.contrib.messages.storage import default_storage
    33
    4 
    54class MessageMiddleware(object):
    65    """
    76    Middleware that handles temporary messages.
  • django/contrib/messages/tests/base.py

    diff -r 78ad3faa689b django/contrib/messages/tests/base.py
    a b  
    103103        storage = self.get_storage()
    104104        self.assertFalse(storage.added_new)
    105105        storage.add(constants.INFO, 'Test message 1')
    106         self.assert_(storage.added_new)
     106        self.assertTrue(storage.added_new)
    107107        storage.add(constants.INFO, 'Test message 2', extra_tags='tag')
    108108        self.assertEqual(len(storage), 2)
    109109
     
    180180            for msg in data['messages']:
    181181                self.assertContains(response, msg)
    182182
     183    def test_with_template_response(self):
     184        settings.MESSAGE_LEVEL = constants.DEBUG
     185        data = {
     186            'messages': ['Test message %d' % x for x in xrange(10)],
     187        }
     188        show_url = reverse('django.contrib.messages.tests.urls.show_template_response')
     189        for level in self.levels.keys():
     190            add_url = reverse('django.contrib.messages.tests.urls.add_template_response',
     191                              args=(level,))
     192            response = self.client.post(add_url, data, follow=True)
     193            self.assertRedirects(response, show_url)
     194            self.assertTrue('messages' in response.context)
     195            for msg in data['messages']:
     196                self.assertContains(response, msg)
     197
     198            # there shouldn't be any messages on second GET request
     199            response = self.client.get(show_url)
     200            for msg in data['messages']:
     201                self.assertNotContains(response, msg)
     202
    183203    def test_multiple_posts(self):
    184204        """
    185205        Tests that messages persist properly when multiple POSTs are made
  • django/contrib/messages/tests/urls.py

    diff -r 78ad3faa689b django/contrib/messages/tests/urls.py
    a b  
    22from django.contrib import messages
    33from django.core.urlresolvers import reverse
    44from django.http import HttpResponseRedirect, HttpResponse
    5 from django.shortcuts import render_to_response
     5from django.shortcuts import render_to_response, redirect
    66from django.template import RequestContext, Template
     7from django.template.response import TemplateResponse
    78
     9TEMPLATE = """{% if messages %}
     10<ul class="messages">
     11    {% for message in messages %}
     12    <li{% if message.tags %} class="{{ message.tags }}"{% endif %}>
     13        {{ message }}
     14    </li>
     15    {% endfor %}
     16</ul>
     17{% endif %}
     18"""
    819
    920def add(request, message_type):
    1021    # don't default to False here, because we want to test that it defaults
     
    1627                                            fail_silently=fail_silently)
    1728        else:
    1829            getattr(messages, message_type)(request, msg)
     30
    1931    show_url = reverse('django.contrib.messages.tests.urls.show')
    2032    return HttpResponseRedirect(show_url)
    2133
     34def add_template_response(request, message_type):
     35    for msg in request.POST.getlist('messages'):
     36        getattr(messages, message_type)(request, msg)
     37
     38    show_url = reverse('django.contrib.messages.tests.urls.show_template_response')
     39    return HttpResponseRedirect(show_url)
    2240
    2341def show(request):
    24     t = Template("""{% if messages %}
    25 <ul class="messages">
    26     {% for message in messages %}
    27     <li{% if message.tags %} class="{{ message.tags }}"{% endif %}>
    28         {{ message }}
    29     </li>
    30     {% endfor %}
    31 </ul>
    32 {% endif %}""")
     42    t = Template(TEMPLATE)
    3343    return HttpResponse(t.render(RequestContext(request)))
    3444
     45def show_template_response(request):
     46    return TemplateResponse(request, Template(TEMPLATE))
    3547
    3648urlpatterns = patterns('',
    3749    ('^add/(debug|info|success|warning|error)/$', add),
    3850    ('^show/$', show),
     51    ('^template_response/add/(debug|info|success|warning|error)/$', add_template_response),
     52    ('^template_response/show/$', show_template_response),
    3953)
  • django/core/handlers/base.py

    diff -r 78ad3faa689b django/core/handlers/base.py
    a b  
    2121    def __init__(self):
    2222        self._request_middleware = self._view_middleware = self._response_middleware = self._exception_middleware = None
    2323
     24
    2425    def load_middleware(self):
    2526        """
    2627        Populate middleware lists from settings.MIDDLEWARE_CLASSES.
     
    3031        from django.conf import settings
    3132        from django.core import exceptions
    3233        self._view_middleware = []
     34        self._template_response_middleware = []
    3335        self._response_middleware = []
    3436        self._exception_middleware = []
    3537
    3638        request_middleware = []
    3739        for middleware_path in settings.MIDDLEWARE_CLASSES:
    3840            try:
    39                 dot = middleware_path.rindex('.')
    40             except ValueError:
    41                 raise exceptions.ImproperlyConfigured('%s isn\'t a middleware module' % middleware_path)
    42             mw_module, mw_classname = middleware_path[:dot], middleware_path[dot+1:]
    43             try:
    44                 mod = import_module(mw_module)
    45             except ImportError, e:
    46                 raise exceptions.ImproperlyConfigured('Error importing middleware %s: "%s"' % (mw_module, e))
    47             try:
    48                 mw_class = getattr(mod, mw_classname)
    49             except AttributeError:
    50                 raise exceptions.ImproperlyConfigured('Middleware module "%s" does not define a "%s" class' % (mw_module, mw_classname))
    51 
    52             try:
    53                 mw_instance = mw_class()
     41                mw_instance = get_middleware_instance(middleware_path)
    5442            except exceptions.MiddlewareNotUsed:
    5543                continue
    5644
     
    5846                request_middleware.append(mw_instance.process_request)
    5947            if hasattr(mw_instance, 'process_view'):
    6048                self._view_middleware.append(mw_instance.process_view)
     49            if hasattr(mw_instance, 'process_template_response'):
     50                self._template_response_middleware.insert(0, mw_instance.process_template_response)
    6151            if hasattr(mw_instance, 'process_response'):
    6252                self._response_middleware.insert(0, mw_instance.process_response)
    6353            if hasattr(mw_instance, 'process_exception'):
     
    164154            urlresolvers.set_urlconf(None)
    165155
    166156        try:
     157            # Apply template response middleware and the bake the response
     158            # if the response can be baked
     159            if hasattr(response, 'bake') and callable(response.bake):
     160                for middleware_method in self._template_response_middleware:
     161                    response = middleware_method(request, response)
     162                response.bake()
     163
    167164            # Apply response middleware, regardless of the response
    168165            for middleware_method in self._response_middleware:
    169166                response = middleware_method(request, response)
     
    241238    if script_url:
    242239        return force_unicode(script_url[:-len(environ.get('PATH_INFO', ''))])
    243240    return force_unicode(environ.get('SCRIPT_NAME', u''))
     241
     242def get_middleware_instance(middleware_path):
     243    """
     244    Returns middleware instance
     245    """
     246    try:
     247        mw_module, mw_classname = middleware_path.rsplit('.', 1)
     248    except ValueError:
     249        raise exceptions.ImproperlyConfigured('%s isn\'t a middleware module' % middleware_path)
     250    try:
     251        mod = import_module(mw_module)
     252    except ImportError, e:
     253        raise exceptions.ImproperlyConfigured('Error importing middleware %s: "%s"' % (mw_module, e))
     254    try:
     255        mw_class = getattr(mod, mw_classname)
     256    except AttributeError:
     257        raise exceptions.ImproperlyConfigured('Middleware module "%s" does not define a "%s" class' % (mw_module, mw_classname))
     258
     259    return mw_class()
  • django/shortcuts/__init__.py

    diff -r 78ad3faa689b django/shortcuts/__init__.py
    a b  
    44for convenience's sake.
    55"""
    66
    7 from django.template import loader
     7from django.template import loader, RequestContext
    88from django.http import HttpResponse, Http404
    99from django.http import HttpResponseRedirect, HttpResponsePermanentRedirect
    1010from django.db.models.manager import Manager
     
    1919    httpresponse_kwargs = {'mimetype': kwargs.pop('mimetype', None)}
    2020    return HttpResponse(loader.render_to_string(*args, **kwargs), **httpresponse_kwargs)
    2121
     22def render(request, *args, **kwargs):
     23    """
     24    Returns a HttpResponse whose content is filled with the result of calling
     25    django.template.loader.render_to_string() with the passed arguments.
     26    Uses a RequestContext by default.
     27    """
     28    httpresponse_kwargs = {'mimetype': kwargs.pop('mimetype', None)}
     29    kwargs['context_instance'] = kwargs.get('context_instance', RequestContext(request))
     30    return HttpResponse(loader.render_to_string(*args, **kwargs),
     31                        **httpresponse_kwargs)
     32
    2233def redirect(to, *args, **kwargs):
    2334    """
    2435    Returns an HttpResponseRedirect to the apropriate URL for the arguments
    2536    passed.
    26    
     37
    2738    The arguments could be:
    28    
     39
    2940        * A model: the model's `get_absolute_url()` function will be called.
    30    
     41
    3142        * A view name, possibly with arguments: `urlresolvers.reverse()` will
    3243          be used to reverse-resolve the name.
    33          
     44
    3445        * A URL, which will be used as-is for the redirect location.
    35        
     46
    3647    By default issues a temporary redirect; pass permanent=True to issue a
    3748    permanent redirect
    3849    """
     
    4051        redirect_class = HttpResponsePermanentRedirect
    4152    else:
    4253        redirect_class = HttpResponseRedirect
    43    
     54
    4455    # If it's a model, use get_absolute_url()
    4556    if hasattr(to, 'get_absolute_url'):
    4657        return redirect_class(to.get_absolute_url())
    47    
     58
    4859    # Next try a reverse URL resolution.
    4960    try:
    5061        return redirect_class(urlresolvers.reverse(to, args=args, kwargs=kwargs))
     
    5566        # If this doesn't "feel" like a URL, re-raise.
    5667        if '/' not in to and '.' not in to:
    5768            raise
    58        
     69
    5970    # Finally, fall back and assume it's a URL
    6071    return redirect_class(to)
    6172
     
    101112    obj_list = list(queryset.filter(*args, **kwargs))
    102113    if not obj_list:
    103114        raise Http404('No %s matches the given query.' % queryset.model._meta.object_name)
    104     return obj_list
    105  No newline at end of file
     115    return obj_list
     116
  • new file django/template/response.py

    diff -r 78ad3faa689b django/template/response.py
    - +  
     1from django.http import HttpResponse
     2from django.template import loader, Context, RequestContext
     3
     4class ContentNotBakedError(Exception):
     5    pass
     6
     7class SimpleTemplateResponse(HttpResponse):
     8
     9    def __init__(self, template, context=None, mimetype=None, status=None,
     10            content_type=None):
     11        # It would seem obvious to call these next two members 'template' and
     12        # 'context', but those names are reserved as part of the test Client API.
     13        # To avoid the name collision, we use
     14        # tricky-to-debug problems
     15        self.template_name = template
     16        self.context_data = context
     17
     18        # _baked tracks whether the template and context has been baked into
     19        # a final response.
     20        self._baked = False
     21
     22        # content argument doesn't make sense here because it will be replaced
     23        # with rendered template so we always pass empty string in order to
     24        # prevent errors and provide shorter signature.
     25        super(SimpleTemplateResponse, self).__init__('', mimetype, status,
     26                                                     content_type)
     27
     28    def resolve_template(self, template):
     29        "Accepts a template object, path-to-template or list of paths"
     30        if isinstance(template, (list, tuple)):
     31            return loader.select_template(template)
     32        elif isinstance(template, basestring):
     33            return loader.get_template(template)
     34        else:
     35            return template
     36
     37    def resolve_context(self, context):
     38        """Convert context data into a full Context object
     39        (assuming it isn't already a Context object).
     40        """
     41        if isinstance(context, Context):
     42            return context
     43        else:
     44            return Context(context)
     45
     46    def render(self):
     47        "Render the content of the response. Returns the rendered content"
     48        template = self.resolve_template(self.template_name)
     49        context = self.resolve_context(self.context_data)
     50        content = template.render(context)
     51        return content
     52
     53    def bake(self):
     54        """Bake the response.
     55
     56        If the content has already been baked, this is a no-op.
     57
     58        Returns the baked response instance.
     59        """
     60        if not self._baked:
     61            self._set_content(self.render())
     62        return self
     63
     64    baked = property(lambda self: self._baked)
     65
     66    def __iter__(self):
     67        if not self._baked:
     68            raise ContentNotBakedError('The response content must be baked before it can be iterated over.')
     69        return super(SimpleTemplateResponse, self).__iter__()
     70
     71    def _get_content(self):
     72        if not self._baked:
     73            raise ContentNotBakedError('The response content must be baked before it can be accessed.')
     74        return super(SimpleTemplateResponse, self)._get_content()
     75
     76    def _set_content(self, value):
     77        "Overrides rendered content, unless you later call bake()"
     78        super(SimpleTemplateResponse, self)._set_content(value)
     79        self._baked = True
     80
     81    content = property(_get_content, _set_content)
     82
     83class TemplateResponse(SimpleTemplateResponse):
     84
     85    def __init__(self, request, template, context=None, mimetype=None,
     86            status=None, content_type=None):
     87        # self.request gets over-written by django.test.client.Client - and
     88        # unlike context_data and template_name the _request should not
     89        # be considered part of the public API.
     90        self._request = request
     91        super(TemplateResponse, self).__init__(
     92            template, context, mimetype, status, content_type)
     93
     94    def resolve_context(self, context):
     95        """Convert context data into a full RequestContext object
     96        (assuming it isn't already a Context object).
     97        """
     98        if isinstance(context, Context):
     99            return context
     100        else:
     101            return RequestContext(self._request, context)
     102
     103def bake(response):
     104    """
     105    Bakes response if it can be baked. Unbakeable instances (such as
     106    normal HttpResponse instances) are unaffected.
     107    """
     108    if (hasattr(response, 'bake') and callable(response.bake)):
     109        response.bake()
  • django/views/generic/base.py

    diff -r 78ad3faa689b django/views/generic/base.py
    a b  
    11from django import http
    22from django.core.exceptions import ImproperlyConfigured
    33from django.template import RequestContext, loader
     4from django.template.response import TemplateResponse
    45from django.utils.functional import update_wrapper
    56from django.utils.log import getLogger
    67from django.utils.decorators import classonlymethod
     
    8182    A mixin that can be used to render a template.
    8283    """
    8384    template_name = None
     85    response_class = TemplateResponse
    8486
    85     def render_to_response(self, context):
     87    def render_to_response(self, context, **response_kwargs):
    8688        """
    8789        Returns a response with a template rendered with the given context.
    8890        """
    89         return self.get_response(self.render_template(context))
    90 
    91     def get_response(self, content, **httpresponse_kwargs):
    92         """
    93         Construct an `HttpResponse` object.
    94         """
    95         return http.HttpResponse(content, **httpresponse_kwargs)
    96 
    97     def render_template(self, context):
    98         """
    99         Render the template with a given context.
    100         """
    101         context_instance = self.get_context_instance(context)
    102         return self.get_template().render(context_instance)
    103 
    104     def get_context_instance(self, context):
    105         """
    106         Get the template context instance. Must return a Context (or subclass)
    107         instance.
    108         """
    109         return RequestContext(self.request, context)
    110 
    111     def get_template(self):
    112         """
    113         Get a ``Template`` object for the given request.
    114         """
    115         names = self.get_template_names()
    116         if not names:
    117             raise ImproperlyConfigured(u"'%s' must provide template_name."
    118                                        % self.__class__.__name__)
    119         return self.load_template(names)
     91        return self.response_class(
     92            request = self.request,
     93            template = self.get_template_names(),
     94            context = context,
     95            **response_kwargs
     96        )
    12097
    12198    def get_template_names(self):
    12299        """
    123         Return a list of template names to be used for the request. Must return
    124         a list. May not be called if get_template is overridden.
     100        Returns a list of template names to be used for the request. Must return
     101        a list. May not be called if render_to_response is overridden.
    125102        """
    126103        if self.template_name is None:
    127104            return []
    128105        else:
    129106            return [self.template_name]
    130107
    131     def load_template(self, names):
    132         """
    133         Load a list of templates using the default template loader.
    134         """
    135         return loader.select_template(names)
    136 
    137108
    138109class TemplateView(TemplateResponseMixin, View):
    139110    """
  • docs/index.txt

    diff -r 78ad3faa689b docs/index.txt
    a b  
    9393      :doc:`View functions <topics/http/views>` |
    9494      :doc:`Shortcuts <topics/http/shortcuts>`
    9595
    96     * **Reference:**  :doc:`Request/response objects <ref/request-response>`
     96    * **Reference:**
     97      :doc:`Request/response objects <ref/request-response>` |
     98      :doc:`TemplateResponse objects <ref/template-response>`
    9799
    98100    * **File uploads:**
    99101      :doc:`Overview <topics/http/file-uploads>` |
  • docs/ref/class-based-views.txt

    diff -r 78ad3faa689b docs/ref/class-based-views.txt
    a b  
    7676
    7777        The path to the template to use when rendering the view.
    7878
    79     .. method:: render_to_response(context)
     79    .. attribute:: response_class
    8080
    81         Returns a full composed HttpResponse instance, ready to be returned to
    82         the user.
     81        The response class to be returned by ``render_to_response`` method.
     82        Default is
     83        :class:`TemplateResponse <django.template.response.TemplateResponse>`.
     84        The template and context of TemplateResponse instances can be
     85        altered later (e.g. in
     86        :ref:`template response middleware <template-response-middleware>`).
    8387
    84         Calls :meth:`~TemplateResponseMixin.render_template()` to build the
    85         content of the response, and
    86         :meth:`~TemplateResponseMixin.get_response()` to construct the
    87         :class:`~django.http.HttpResponse` object.
     88        Create TemplateResponse subclass and pass set it to
     89        ``template_response_class`` if you need custom template loading or
     90        custom context object instantiation.
    8891
    89     .. method:: get_response(content, **httpresponse_kwargs)
     92    .. method:: render_to_response(context, **response_kwargs)
    9093
    91         Constructs the :class:`~django.http.HttpResponse` object around the
    92         given content. If any keyword arguments are provided, they will be
    93         passed to the constructor of the :class:`~django.http.HttpResponse`
    94         instance.
     94        Returns a ``self.template_response_class`` instance.
    9595
    96     .. method:: render_template(context)
    97 
    98         Calls :meth:`~TemplateResponseMixin.get_context_instance()` to obtain
    99         the :class:`Context` instance to use for rendering, and calls
    100         :meth:`TemplateReponseMixin.get_template()` to load the template that
    101         will be used to render the final content.
    102 
    103     .. method:: get_context_instance(context)
    104 
    105         Turns the data dictionary ``context`` into an actual context instance
    106         that can be used for rendering.
    107 
    108         By default, constructs a :class:`~django.template.RequestContext`
    109         instance.
    110 
    111     .. method:: get_template()
     96        If any keyword arguments are provided, they will be
     97        passed to the constructor of the response instance.
    11298
    11399        Calls :meth:`~TemplateResponseMixin.get_template_names()` to obtain the
    114100        list of template names that will be searched looking for an existent
     
    123109        default implementation will return a list containing
    124110        :attr:`TemplateResponseMixin.template_name` (if it is specified).
    125111
    126     .. method:: load_template(names)
    127 
    128         Loads and returns a template found by searching the list of ``names``
    129         for a match. Uses Django's default template loader.
    130112
    131113Single object mixins
    132114--------------------
  • docs/ref/index.txt

    diff -r 78ad3faa689b docs/ref/index.txt
    a b  
    1616   middleware
    1717   models/index
    1818   request-response
     19   template-response
    1920   settings
    2021   signals
    2122   templates/index
  • new file docs/ref/template-response.txt

    diff -r 78ad3faa689b docs/ref/template-response.txt
    - +  
     1===========================================
     2TemplateResponse and SimpleTemplateResponse
     3===========================================
     4
     5.. versionadded:: 1.3
     6
     7.. module:: django.template.response
     8   :synopsis: Classes dealing with lazy-rendered HTTP responses.
     9
     10Standard HttpResponse objects are static structures. They are provided
     11with a block of pre-rendered content at time of construction, and
     12while that content can be modified, it isn't in a form that makes it
     13easy to perform modifications.
     14
     15However, it can sometimes be beneficial to allow decorators or
     16middleware to modify a response *after* it has been constructed by the
     17view. For example, you may want to change the template that is used,
     18or put additional data into the context.
     19
     20TemplateResponse provides a way to do just that. Unlike basic
     21HttpResponse objects, TemplateResponse objects retain the details of
     22the template and context that was provided by the view to compute the
     23response. The final output of the response is not computed until
     24it is needed.
     25
     26TemplateResponse objects
     27========================
     28
     29.. class:: SimpleTemplateResponse()
     30
     31Attributes
     32----------
     33
     34.. attribute:: SimpleTemplateResponse.template_name
     35
     36    The name of the template to be rendered. Accepts
     37    :class:`django.template.Template` object, path to template or list
     38    of paths.
     39
     40    Example: ``['foo.html', 'path/to/bar.html']``
     41
     42.. attribute:: SimpleTemplateResponse.context_data
     43
     44    The context data to be used when rendering the template. It can be
     45    a dictionary or a context object.
     46
     47    Example: ``{'foo': 123}``
     48
     49
     50Methods
     51-------
     52
     53.. method:: SimpleTemplateResponse.__init__(template, context=None, mimetype=None, status=None, content_type=None)
     54
     55    Instantiates an
     56    :class:`~django.template.response.SimpleTemplateResponse` object
     57    with the given template, context, MIME type and HTTP status.
     58
     59    ``template`` is a full name of a template, or a sequence of
     60    template names. :class:`django.template.Template` instances can also be used.
     61
     62    ``context`` is a dictionary of values to add to the template context.
     63    By default, this is an empty dictionary. :class:`~django.template.Context` objects are also
     64    accepted as ``context`` values.
     65
     66    ``status`` is the HTTP Status code for the response.
     67
     68    ``content_type`` is an alias for ``mimetype``. Historically, this parameter
     69    was only called ``mimetype``, but since this is actually the value included
     70    in the HTTP ``Content-Type`` header, it can also include the character set
     71    encoding, which makes it more than just a MIME type specification.
     72    If ``mimetype`` is specified (not ``None``), that value is used.
     73    Otherwise, ``content_type`` is used. If neither is given, the
     74    ``DEFAULT_CONTENT_TYPE`` setting is used.
     75
     76
     77.. method:: SimpleTemplateResponse.resolve_context(context)
     78
     79    Converts context data into a context instance that can be used for
     80    rendering a template. Accepts a dictionary of context data or a
     81    context object. Returns a :class:`~django.template.Context`
     82    instance containing the provided data.
     83
     84    Override this method in order to customize context instantiation.
     85
     86.. method:: SimpleTemplateResponse.resolve_template(template)
     87
     88    Resolves the template instance to use for rendering. Accepts a
     89    path of a template to use, or a sequence of template paths.
     90    :class:`~django.template.Template` instances may also be provided.
     91    Returns the :class:`~django.template.Template` instance to be
     92    rendered.
     93
     94    Override this method in order to customize template rendering.
     95
     96.. method:: SimpleTemplateResponse.render():
     97
     98    Renders a template instance returned by
     99    :meth:`SimpleTemplateResponse.resolve_template` using the context instance
     100    returned by :meth:`SimpleTemplateResponse.resolve_context` and returns the
     101    rendered content.
     102
     103.. method:: SimpleTemplateResponse.bake():
     104
     105    Bakes the response by setting :attr:`response.content` to the result
     106    returned by :meth:`SimpleTemplateResponse.render`.
     107
     108    The response is baked by Django during response middleware cycle. You should
     109    only bake the response yourself if it is to be used outside the
     110    request-response cycle (e.g. for debugging). It will be baked twice
     111    otherwise.
     112
     113
     114.. class:: TemplateResponse()
     115
     116   TemplateResponse is a subclass of
     117   :class:`SimpleTemplateResponse <django.template.response.SimpleTemplateResponse>`
     118   that uses RequestContext instead of Context.
     119
     120.. method:: TemplateResponse.__init__(request, template, context=None, mimetype=None, status=None, content_type=None)
     121
     122   Instantiates an ``TemplateResponse`` object with the given template,
     123   context, MIME type and HTTP status.
     124
     125   ``request`` is a HttpRequest instance.
     126
     127   ``template`` is a full name of a template to use or sequence of
     128   template names. :class:`django.template.Template` instances are also
     129   accepted.
     130
     131   ``context`` is a dictionary of values to add to the template context.
     132   By default, this is an empty dictionary; context objects are also accepted
     133   as ``context`` values.
     134
     135   ``status`` is the HTTP Status code for the response.
     136
     137   ``content_type`` is an alias for ``mimetype``. Historically, this parameter
     138   was only called ``mimetype``, but since this is actually the value included
     139   in the HTTP ``Content-Type`` header, it can also include the character set
     140   encoding, which makes it more than just a MIME type specification.
     141   If ``mimetype`` is specified (not ``None``), that value is used.
     142   Otherwise, ``content_type`` is used. If neither is given, the
     143   ``DEFAULT_CONTENT_TYPE`` setting is used.
     144
     145
     146Baking
     147======
     148
     149*Baking* is the process by which the content in a TemplateResponse is
     150converted into the final form that will be returned to the client.
     151
     152There are three circumstances under which a TemplateResponse is baked:
     153
     154    * When the TemplateResponse instance is explicitly baked, using
     155      the :meth:`bake()` method.
     156
     157    * When the content of the response is explicitly set by assigning
     158      :attr:`response.content`.
     159
     160    * After passing through template response middleware, but before
     161      passing through response middleware.
     162
     163A TemplateResponse can only be baked once. The first call to
     164:meth:`bake()` sets the content of the response; subsequent baking
     165calls do not change the response content.
     166
     167However, when :attr:`response.content` is explicitly assigned, the
     168change is always applied. If you want to force templated content to be
     169rebaked, you can re-render the content and assign it::
     170
     171    # Set up a baked TemplateResponse
     172    >>> t = TemplateResponse(request, 'original.html', {})
     173    >>> t.bake()
     174    >>> print t.content
     175    Original content
     176
     177    # Rebaking doesn't change content
     178    >>> t.template_name = 'other.html'
     179    >>> t.bake()
     180    >>> print t.content
     181    Original content
     182
     183    # Assigning content does change
     184    >>> t.content = t.render()
     185    >>> print t.content
     186    Other content
     187
     188Using TemplateResponse and SimpleTemplateResponse
     189=================================================
     190
     191A TemplateResponse object can be used anywhere that a normal
     192HttpResponse can be used. It can also be used as an alternative to
     193calling render_to_response().
     194
     195For example, the following simple view returns a TemplateResponse
     196with a simple template, and a context containing a queryset::
     197
     198    from django.template.response import TemplateResponse
     199
     200    def blog_index(request):
     201        return TemplateResponse(request, 'entry_list.html', {'entries': Entry.objects.all()})
  • docs/topics/http/middleware.txt

    diff -r 78ad3faa689b docs/topics/http/middleware.txt
    a b  
    120120classes are applied in reverse order, from the bottom up. This means classes
    121121defined at the end of :setting:`MIDDLEWARE_CLASSES` will be run first.
    122122
     123.. _template-response-middleware:
     124
     125``process_template_response``
     126-----------------------------
     127
     128.. versionadded:: 1.3
     129
     130.. method:: process_template_response(self, request, response)
     131
     132``request`` is an :class:`~django.http.HttpRequest` object. ``response`` is the
     133:class:`~django.template.response.SimpleTemplateResponse` subclass (e.g.
     134:class:`~django.template.response.TemplateResponse`) object returned by a
     135Django view.
     136
     137``process_template_response()`` must return an
     138:class:`~django.template.response.SimpleTemplateResponse` (or it's subclass)
     139object. It could alter the given ``response`` by changing
     140``response.template_name`` and ``response.template_context``, or it could
     141create and return a brand-new
     142:class:`~django.template.response.SimpleTemplateResponse` (or it's subclass)
     143instance.
     144
     145``process_template_response()`` is only called on response instances that
     146can be baked. It is called before the ``process_response()`` method.
     147
     148You don't need to explicitly bake responses -- responses will be automatically baked
     149once all template response middleware has been called.
     150
     151Middleware are run in reverse order during the response phase, which
     152includes process_template_response.
     153
    123154.. _exception-middleware:
    124155
    125156``process_exception``
     
    137168the browser. Otherwise, default exception handling kicks in.
    138169
    139170Again, middleware are run in reverse order during the response phase, which
    140 includes ``process_exception``. If an exception middleware return a response,
     171includes ``process_exception``. If an exception middleware returns a response,
    141172the middleware classes above that middleware will not be called at all.
    142173
    143174``__init__``
  • docs/topics/http/shortcuts.txt

    diff -r 78ad3faa689b docs/topics/http/shortcuts.txt
    a b  
    1212"span" multiple levels of MVC. In other words, these functions/classes
    1313introduce controlled coupling for convenience's sake.
    1414
     15``render``
     16==========
     17
     18.. function:: render(request, template[, dictionary][, context_instance][, mimetype])
     19
     20   Combines a given template with a given context dictionary and returns an
     21   :class:`~django.http.HttpResponse` object with that rendered text.
     22
     23   :func:`render()` is the same as a call to
     24   :func:`render_to_response()` with a context_instance argument that
     25   that forces the use of a :class:`RequestContext`.
     26
     27Required arguments
     28------------------
     29
     30``request``
     31    The request object used to generate this response.
     32
     33``template``
     34    The full name of a template to use or sequence of template names.
     35
     36Optional arguments
     37------------------
     38
     39``dictionary``
     40    A dictionary of values to add to the template context. By default, this
     41    is an empty dictionary. If a value in the dictionary is callable, the
     42    view will call it just before rendering the template.
     43
     44``context_instance``
     45    The context instance to render the template with. By default, the template
     46    will be rendered with a ``RequestContext`` instance (filled with values from
     47    ``request`` and ```dictionary``).
     48
     49``mimetype``
     50    The MIME type to use for the resulting document. Defaults to the value of
     51    the :setting:`DEFAULT_CONTENT_TYPE` setting.
     52
     53Example
     54-------
     55
     56The following example renders the template ``myapp/index.html`` with the
     57MIME type ``application/xhtml+xml``::
     58
     59    from django.shortcuts import render_to_response
     60
     61    def my_view(request):
     62        # View code here...
     63        return render_to_response('myapp/index.html', {"foo": "bar"},
     64            mimetype="application/xhtml+xml")
     65
     66This example is equivalent to::
     67
     68    from django.http import HttpResponse
     69    from django.template import Context, loader
     70
     71    def my_view(request):
     72        # View code here...
     73        t = loader.get_template('myapp/template.html')
     74        c = RequestContext(request, {'foo': 'bar'})
     75        return HttpResponse(t.render(c),
     76            mimetype="application/xhtml+xml")
     77
     78
    1579``render_to_response``
    1680======================
    1781
  • tests/regressiontests/generic_views/base.py

    diff -r 78ad3faa689b tests/regressiontests/generic_views/base.py
    a b  
    156156    rf = RequestFactory()
    157157
    158158    def _assert_about(self, response):
     159        response.bake()
    159160        self.assertEqual(response.status_code, 200)
    160161        self.assertEqual(response.content, '<h1>About</h1>')
    161162
  • tests/regressiontests/middleware_exceptions/tests.py

    diff -r 78ad3faa689b tests/regressiontests/middleware_exceptions/tests.py
    a b  
    33from django.conf import settings
    44from django.core.signals import got_request_exception
    55from django.http import HttpResponse
     6from django.template.response import TemplateResponse
     7from django.template import Template
    68from django.test import TestCase
    79
    8 
    910class TestException(Exception):
    1011    pass
    1112
     
    1617        self.process_request_called = False
    1718        self.process_view_called = False
    1819        self.process_response_called = False
     20        self.process_template_response_called = False
    1921        self.process_exception_called = False
    2022
    2123    def process_request(self, request):
     
    2426    def process_view(self, request, view_func, view_args, view_kwargs):
    2527        self.process_view_called = True
    2628
     29    def process_template_response(self, request, response):
     30        self.process_template_response_called = True
     31        return response
     32
    2733    def process_response(self, request, response):
    2834        self.process_response_called = True
    2935        return response
     
    4854        super(ResponseMiddleware, self).process_response(request, response)
    4955        return HttpResponse('Response Middleware')
    5056
     57class TemplateResponseMiddleware(TestMiddleware):
     58    def process_template_response(self, request, response):
     59        super(TemplateResponseMiddleware, self).process_template_response(request, response)
     60        return TemplateResponse(request, Template('Template Response Middleware'))
     61
    5162class ExceptionMiddleware(TestMiddleware):
    5263    def process_exception(self, request, exception):
    5364        super(ExceptionMiddleware, self).process_exception(request, exception)
     
    6677        super(BadViewMiddleware, self).process_view(request, view_func, view_args, view_kwargs)
    6778        raise TestException('Test View Exception')
    6879
     80class BadTemplateResponseMiddleware(TestMiddleware):
     81    def process_template_response(self, request, response):
     82        super(BadTemplateResponseMiddleware, self).process_template_response(request, response)
     83        raise TestException('Test Template Response Exception')
     84
    6985class BadResponseMiddleware(TestMiddleware):
    7086    def process_response(self, request, response):
    7187        super(BadResponseMiddleware, self).process_response(request, response)
     
    93109    def _add_middleware(self, middleware):
    94110        self.client.handler._request_middleware.insert(0, middleware.process_request)
    95111        self.client.handler._view_middleware.insert(0, middleware.process_view)
     112        self.client.handler._template_response_middleware.append(middleware.process_template_response)
    96113        self.client.handler._response_middleware.append(middleware.process_response)
    97114        self.client.handler._exception_middleware.append(middleware.process_exception)
    98115
     
    113130            exception, value, tb = self.exceptions[i]
    114131            self.assertEquals(value.args, (error, ))
    115132
    116     def assert_middleware_usage(self, middleware, request, view, response, exception):
     133    def assert_middleware_usage(self, middleware, request, view, template_response, response, exception):
    117134        self.assertEqual(middleware.process_request_called, request)
    118135        self.assertEqual(middleware.process_view_called, view)
     136        self.assertEqual(middleware.process_template_response_called, template_response)
    119137        self.assertEqual(middleware.process_response_called, response)
    120138        self.assertEqual(middleware.process_exception_called, exception)
    121139
     
    132150        self.assert_exceptions_handled('/middleware_exceptions/view/', [])
    133151
    134152        # Check that the right middleware methods have been invoked
    135         self.assert_middleware_usage(pre_middleware,  True,  False, True, False)
    136         self.assert_middleware_usage(middleware,      True,  False, True, False)
    137         self.assert_middleware_usage(post_middleware, False, False, True, False)
     153        self.assert_middleware_usage(pre_middleware,  True,  False, False, True, False)
     154        self.assert_middleware_usage(middleware,      True,  False, False, True, False)
     155        self.assert_middleware_usage(post_middleware, False, False, False, True, False)
    138156
    139157    def test_process_view_middleware(self):
    140158        pre_middleware = TestMiddleware()
     
    146164        self.assert_exceptions_handled('/middleware_exceptions/view/', [])
    147165
    148166        # Check that the right middleware methods have been invoked
    149         self.assert_middleware_usage(pre_middleware,  True,  True, True, False)
    150         self.assert_middleware_usage(middleware,      True,  True, True, False)
    151         self.assert_middleware_usage(post_middleware, True, False, True, False)
     167        self.assert_middleware_usage(pre_middleware,  True, True,  False, True, False)
     168        self.assert_middleware_usage(middleware,      True, True,  False, True, False)
     169        self.assert_middleware_usage(post_middleware, True, False, False, True, False)
    152170
    153171    def test_process_response_middleware(self):
    154172        pre_middleware = TestMiddleware()
     
    160178        self.assert_exceptions_handled('/middleware_exceptions/view/', [])
    161179
    162180        # Check that the right middleware methods have been invoked
    163         self.assert_middleware_usage(pre_middleware,  True,  True,  True,  False)
    164         self.assert_middleware_usage(middleware,      True,  True,  True,  False)
    165         self.assert_middleware_usage(post_middleware, True,  True,  True,  False)
     181        self.assert_middleware_usage(pre_middleware,  True, True, False, True, False)
     182        self.assert_middleware_usage(middleware,      True, True, False, True, False)
     183        self.assert_middleware_usage(post_middleware, True, True, False, True, False)
     184
     185    def test_process_template_response_middleware(self):
     186        pre_middleware = TestMiddleware()
     187        middleware = TemplateResponseMiddleware()
     188        post_middleware = TestMiddleware()
     189        self._add_middleware(post_middleware)
     190        self._add_middleware(middleware)
     191        self._add_middleware(pre_middleware)
     192        self.assert_exceptions_handled('/middleware_exceptions/template_response/', [])
     193
     194        # Check that the right middleware methods have been invoked
     195        self.assert_middleware_usage(pre_middleware,  True, True, True, True, False)
     196        self.assert_middleware_usage(middleware,      True, True, True, True, False)
     197        self.assert_middleware_usage(post_middleware, True, True, True, True, False)
    166198
    167199    def test_process_exception_middleware(self):
    168200        pre_middleware = TestMiddleware()
     
    174206        self.assert_exceptions_handled('/middleware_exceptions/view/', [])
    175207
    176208        # Check that the right middleware methods have been invoked
    177         self.assert_middleware_usage(pre_middleware,  True,  True, True, False)
    178         self.assert_middleware_usage(middleware,      True,  True, True, False)
    179         self.assert_middleware_usage(post_middleware, True,  True, True, False)
     209        self.assert_middleware_usage(pre_middleware,  True, True, False, True, False)
     210        self.assert_middleware_usage(middleware,      True, True, False, True, False)
     211        self.assert_middleware_usage(post_middleware, True, True, False, True, False)
    180212
    181213    def test_process_request_middleware_not_found(self):
    182214        pre_middleware = TestMiddleware()
     
    188220        self.assert_exceptions_handled('/middleware_exceptions/not_found/', [])
    189221
    190222        # Check that the right middleware methods have been invoked
    191         self.assert_middleware_usage(pre_middleware,  True,  False, True, False)
    192         self.assert_middleware_usage(middleware,      True,  False, True, False)
    193         self.assert_middleware_usage(post_middleware, False, False, True, False)
     223        self.assert_middleware_usage(pre_middleware,  True,  False, False, True, False)
     224        self.assert_middleware_usage(middleware,      True,  False, False, True, False)
     225        self.assert_middleware_usage(post_middleware, False, False, False, True, False)
    194226
    195227    def test_process_view_middleware_not_found(self):
    196228        pre_middleware = TestMiddleware()
     
    202234        self.assert_exceptions_handled('/middleware_exceptions/not_found/', [])
    203235
    204236        # Check that the right middleware methods have been invoked
    205         self.assert_middleware_usage(pre_middleware,  True,  True,  True, False)
    206         self.assert_middleware_usage(middleware,      True,  True,  True, False)
    207         self.assert_middleware_usage(post_middleware, True,  False, True, False)
     237        self.assert_middleware_usage(pre_middleware,  True, True,  False, True, False)
     238        self.assert_middleware_usage(middleware,      True, True,  False, True, False)
     239        self.assert_middleware_usage(post_middleware, True, False, False, True, False)
     240
     241    def test_process_template_response_middleware_not_found(self):
     242        pre_middleware = TestMiddleware()
     243        middleware = TemplateResponseMiddleware()
     244        post_middleware = TestMiddleware()
     245        self._add_middleware(post_middleware)
     246        self._add_middleware(middleware)
     247        self._add_middleware(pre_middleware)
     248        self.assert_exceptions_handled('/middleware_exceptions/not_found/', [])
     249
     250        # Check that the right middleware methods have been invoked
     251        self.assert_middleware_usage(pre_middleware,  True, True, False, True, True)
     252        self.assert_middleware_usage(middleware,      True, True, False, True, True)
     253        self.assert_middleware_usage(post_middleware, True, True, False, True, True)
    208254
    209255    def test_process_response_middleware_not_found(self):
    210256        pre_middleware = TestMiddleware()
     
    216262        self.assert_exceptions_handled('/middleware_exceptions/not_found/', [])
    217263
    218264        # Check that the right middleware methods have been invoked
    219         self.assert_middleware_usage(pre_middleware,  True,  True,  True, True)
    220         self.assert_middleware_usage(middleware,      True,  True,  True, True)
    221         self.assert_middleware_usage(post_middleware, True,  True,  True, True)
     265        self.assert_middleware_usage(pre_middleware,  True, True, False, True, True)
     266        self.assert_middleware_usage(middleware,      True, True, False, True, True)
     267        self.assert_middleware_usage(post_middleware, True, True, False, True, True)
    222268
    223269    def test_process_exception_middleware_not_found(self):
    224270        pre_middleware = TestMiddleware()
     
    230276        self.assert_exceptions_handled('/middleware_exceptions/not_found/', [])
    231277
    232278        # Check that the right middleware methods have been invoked
    233         self.assert_middleware_usage(pre_middleware,  True,  True, True, False)
    234         self.assert_middleware_usage(middleware,      True,  True,  True, True)
    235         self.assert_middleware_usage(post_middleware, True,  True,  True, True)
     279        self.assert_middleware_usage(pre_middleware,  True, True, False, True, False)
     280        self.assert_middleware_usage(middleware,      True, True, False, True, True)
     281        self.assert_middleware_usage(post_middleware, True, True, False, True, True)
    236282
    237283    def test_process_request_middleware_exception(self):
    238284        pre_middleware = TestMiddleware()
     
    244290        self.assert_exceptions_handled('/middleware_exceptions/error/', [])
    245291
    246292        # Check that the right middleware methods have been invoked
    247         self.assert_middleware_usage(pre_middleware,  True,  False, True, False)
    248         self.assert_middleware_usage(middleware,  True,  False, True, False)
    249         self.assert_middleware_usage(post_middleware, False, False, True, False)
     293        self.assert_middleware_usage(pre_middleware,  True,  False, False, True, False)
     294        self.assert_middleware_usage(middleware,      True,  False, False, True, False)
     295        self.assert_middleware_usage(post_middleware, False, False, False, True, False)
    250296
    251297    def test_process_view_middleware_exception(self):
    252298        pre_middleware = TestMiddleware()
     
    258304        self.assert_exceptions_handled('/middleware_exceptions/error/', [])
    259305
    260306        # Check that the right middleware methods have been invoked
    261         self.assert_middleware_usage(pre_middleware,  True,  True, True, False)
    262         self.assert_middleware_usage(middleware,      True,  True, True, False)
    263         self.assert_middleware_usage(post_middleware, True, False, True, False)
     307        self.assert_middleware_usage(pre_middleware,  True, True,  False, True, False)
     308        self.assert_middleware_usage(middleware,      True, True,  False, True, False)
     309        self.assert_middleware_usage(post_middleware, True, False, False, True, False)
    264310
    265311    def test_process_response_middleware_exception(self):
    266312        pre_middleware = TestMiddleware()
     
    272318        self.assert_exceptions_handled('/middleware_exceptions/error/', ['Error in view'], Exception())
    273319
    274320        # Check that the right middleware methods have been invoked
    275         self.assert_middleware_usage(pre_middleware,  True,  True,  True, True)
    276         self.assert_middleware_usage(middleware,      True,  True,  True, True)
    277         self.assert_middleware_usage(post_middleware, True,  True,  True, True)
     321        self.assert_middleware_usage(pre_middleware,  True, True, False, True, True)
     322        self.assert_middleware_usage(middleware,      True, True, False, True, True)
     323        self.assert_middleware_usage(post_middleware, True, True, False, True, True)
    278324
    279325    def test_process_exception_middleware_exception(self):
    280326        pre_middleware = TestMiddleware()
     
    286332        self.assert_exceptions_handled('/middleware_exceptions/error/', [])
    287333
    288334        # Check that the right middleware methods have been invoked
    289         self.assert_middleware_usage(pre_middleware,  True,  True, True, False)
    290         self.assert_middleware_usage(middleware,      True,  True,  True, True)
    291         self.assert_middleware_usage(post_middleware, True,  True,  True, True)
     335        self.assert_middleware_usage(pre_middleware,  True, True, False, True, False)
     336        self.assert_middleware_usage(middleware,      True, True, False, True, True)
     337        self.assert_middleware_usage(post_middleware, True, True, False, True, True)
    292338
    293339    def test_process_request_middleware_null_view(self):
    294340        pre_middleware = TestMiddleware()
     
    300346        self.assert_exceptions_handled('/middleware_exceptions/null_view/', [])
    301347
    302348        # Check that the right middleware methods have been invoked
    303         self.assert_middleware_usage(pre_middleware,  True,  False, True, False)
    304         self.assert_middleware_usage(middleware,      True,  False, True, False)
    305         self.assert_middleware_usage(post_middleware, False, False, True, False)
     349        self.assert_middleware_usage(pre_middleware,  True,  False, False, True, False)
     350        self.assert_middleware_usage(middleware,      True,  False, False, True, False)
     351        self.assert_middleware_usage(post_middleware, False, False, False, True, False)
    306352
    307353    def test_process_view_middleware_null_view(self):
    308354        pre_middleware = TestMiddleware()
     
    314360        self.assert_exceptions_handled('/middleware_exceptions/null_view/', [])
    315361
    316362        # Check that the right middleware methods have been invoked
    317         self.assert_middleware_usage(pre_middleware,  True,  True, True, False)
    318         self.assert_middleware_usage(middleware,      True,  True, True, False)
    319         self.assert_middleware_usage(post_middleware, True, False, True, False)
     363        self.assert_middleware_usage(pre_middleware,  True, True,  False, True, False)
     364        self.assert_middleware_usage(middleware,      True, True,  False, True, False)
     365        self.assert_middleware_usage(post_middleware, True, False, False, True, False)
    320366
    321367    def test_process_response_middleware_null_view(self):
    322368        pre_middleware = TestMiddleware()
     
    331377            ValueError())
    332378
    333379        # Check that the right middleware methods have been invoked
    334         self.assert_middleware_usage(pre_middleware,  True,  True,  True, False)
    335         self.assert_middleware_usage(middleware,      True,  True,  True, False)
    336         self.assert_middleware_usage(post_middleware, True,  True,  True, False)
     380        self.assert_middleware_usage(pre_middleware,  True, True, False, True, False)
     381        self.assert_middleware_usage(middleware,      True, True, False, True, False)
     382        self.assert_middleware_usage(post_middleware, True, True, False, True, False)
    337383
    338384    def test_process_exception_middleware_null_view(self):
    339385        pre_middleware = TestMiddleware()
     
    348394            ValueError())
    349395
    350396        # Check that the right middleware methods have been invoked
    351         self.assert_middleware_usage(pre_middleware,  True,  True, True, False)
    352         self.assert_middleware_usage(middleware,      True,  True, True, False)
    353         self.assert_middleware_usage(post_middleware, True,  True, True, False)
     397        self.assert_middleware_usage(pre_middleware,  True, True, False, True, False)
     398        self.assert_middleware_usage(middleware,      True, True, False, True, False)
     399        self.assert_middleware_usage(post_middleware, True, True, False, True, False)
    354400
    355401    def test_process_request_middleware_permission_denied(self):
    356402        pre_middleware = TestMiddleware()
     
    362408        self.assert_exceptions_handled('/middleware_exceptions/permission_denied/', [])
    363409
    364410        # Check that the right middleware methods have been invoked
    365         self.assert_middleware_usage(pre_middleware,  True,  False, True, False)
    366         self.assert_middleware_usage(middleware,      True,  False, True, False)
    367         self.assert_middleware_usage(post_middleware, False, False, True, False)
     411        self.assert_middleware_usage(pre_middleware,  True,  False, False, True, False)
     412        self.assert_middleware_usage(middleware,      True,  False, False, True, False)
     413        self.assert_middleware_usage(post_middleware, False, False, False, True, False)
    368414
    369415    def test_process_view_middleware_permission_denied(self):
    370416        pre_middleware = TestMiddleware()
     
    376422        self.assert_exceptions_handled('/middleware_exceptions/permission_denied/', [])
    377423
    378424        # Check that the right middleware methods have been invoked
    379         self.assert_middleware_usage(pre_middleware,  True,  True, True, False)
    380         self.assert_middleware_usage(middleware,      True,  True, True, False)
    381         self.assert_middleware_usage(post_middleware, True, False, True, False)
     425        self.assert_middleware_usage(pre_middleware,  True, True,  False, True, False)
     426        self.assert_middleware_usage(middleware,      True, True,  False, True, False)
     427        self.assert_middleware_usage(post_middleware, True, False, False, True, False)
    382428
    383429    def test_process_response_middleware_permission_denied(self):
    384430        pre_middleware = TestMiddleware()
     
    390436        self.assert_exceptions_handled('/middleware_exceptions/permission_denied/', [])
    391437
    392438        # Check that the right middleware methods have been invoked
    393         self.assert_middleware_usage(pre_middleware,  True,  True,  True, True)
    394         self.assert_middleware_usage(middleware,      True,  True,  True, True)
    395         self.assert_middleware_usage(post_middleware, True,  True,  True, True)
     439        self.assert_middleware_usage(pre_middleware,  True, True, False, True, True)
     440        self.assert_middleware_usage(middleware,      True, True, False, True, True)
     441        self.assert_middleware_usage(post_middleware, True, True, False, True, True)
    396442
    397443    def test_process_exception_middleware_permission_denied(self):
    398444        pre_middleware = TestMiddleware()
     
    404450        self.assert_exceptions_handled('/middleware_exceptions/permission_denied/', [])
    405451
    406452        # Check that the right middleware methods have been invoked
    407         self.assert_middleware_usage(pre_middleware,  True,  True,  True, False)
    408         self.assert_middleware_usage(middleware,  True,  True,  True,  True)
    409         self.assert_middleware_usage(post_middleware, True,  True,  True,  True)
     453        self.assert_middleware_usage(pre_middleware,  True, True, False, True, False)
     454        self.assert_middleware_usage(middleware,      True, True, False, True, True)
     455        self.assert_middleware_usage(post_middleware, True, True, False, True, True)
     456
     457    def test_process_template_response_error(self):
     458        middleware = TestMiddleware()
     459        self._add_middleware(middleware)
     460        self.assert_exceptions_handled('/middleware_exceptions/template_response_error/', [])
     461
     462        # Check that the right middleware methods have been invoked
     463        self.assert_middleware_usage(middleware, True, True, True, True, False)
     464
    410465
    411466class BadMiddlewareTests(BaseMiddlewareExceptionTest):
    412467
     
    420475        self.assert_exceptions_handled('/middleware_exceptions/view/', ['Test Request Exception'])
    421476
    422477        # Check that the right middleware methods have been invoked
    423         self.assert_middleware_usage(pre_middleware,  True,  False, True, False)
    424         self.assert_middleware_usage(bad_middleware,  True,  False, True, False)
    425         self.assert_middleware_usage(post_middleware, False, False, True, False)
     478        self.assert_middleware_usage(pre_middleware,  True,  False, False, True, False)
     479        self.assert_middleware_usage(bad_middleware,  True,  False, False, True, False)
     480        self.assert_middleware_usage(post_middleware, False, False, False, True, False)
    426481
    427482    def test_process_view_bad_middleware(self):
    428483        pre_middleware = TestMiddleware()
     
    434489        self.assert_exceptions_handled('/middleware_exceptions/view/', ['Test View Exception'])
    435490
    436491        # Check that the right middleware methods have been invoked
    437         self.assert_middleware_usage(pre_middleware,  True,  True,  True, False)
    438         self.assert_middleware_usage(bad_middleware,  True,  True,  True, False)
    439         self.assert_middleware_usage(post_middleware, True,  False, True, False)
     492        self.assert_middleware_usage(pre_middleware,  True, True,  False, True, False)
     493        self.assert_middleware_usage(bad_middleware,  True, True,  False, True, False)
     494        self.assert_middleware_usage(post_middleware, True, False, False, True, False)
     495
     496    def test_process_template_response_bad_middleware(self):
     497        pre_middleware = TestMiddleware()
     498        bad_middleware = BadTemplateResponseMiddleware()
     499        post_middleware = TestMiddleware()
     500        self._add_middleware(post_middleware)
     501        self._add_middleware(bad_middleware)
     502        self._add_middleware(pre_middleware)
     503        self.assert_exceptions_handled('/middleware_exceptions/template_response/', ['Test Template Response Exception'])
     504
     505        # Check that the right middleware methods have been invoked
     506        self.assert_middleware_usage(pre_middleware,  True, True, False, False, False)
     507        self.assert_middleware_usage(bad_middleware,  True, True, True,  False, False)
     508        self.assert_middleware_usage(post_middleware, True, True, True,  False, False)
    440509
    441510    def test_process_response_bad_middleware(self):
    442511        pre_middleware = TestMiddleware()
     
    448517        self.assert_exceptions_handled('/middleware_exceptions/view/', ['Test Response Exception'])
    449518
    450519        # Check that the right middleware methods have been invoked
    451         self.assert_middleware_usage(pre_middleware,  True,  True, False, False)
    452         self.assert_middleware_usage(bad_middleware,  True,  True, True,  False)
    453         self.assert_middleware_usage(post_middleware, True,  True, True,  False)
     520        self.assert_middleware_usage(pre_middleware,  True, True, False, False, False)
     521        self.assert_middleware_usage(bad_middleware,  True, True, False, True,  False)
     522        self.assert_middleware_usage(post_middleware, True, True, False, True,  False)
    454523
    455524    def test_process_exception_bad_middleware(self):
    456525        pre_middleware = TestMiddleware()
     
    462531        self.assert_exceptions_handled('/middleware_exceptions/view/', [])
    463532
    464533        # Check that the right middleware methods have been invoked
    465         self.assert_middleware_usage(pre_middleware,  True,  True, True, False)
    466         self.assert_middleware_usage(bad_middleware,  True,  True, True, False)
    467         self.assert_middleware_usage(post_middleware, True,  True, True, False)
     534        self.assert_middleware_usage(pre_middleware,  True, True, False, True, False)
     535        self.assert_middleware_usage(bad_middleware,  True, True, False, True, False)
     536        self.assert_middleware_usage(post_middleware, True, True, False, True, False)
    468537
    469538    def test_process_request_bad_middleware_not_found(self):
    470539        pre_middleware = TestMiddleware()
     
    476545        self.assert_exceptions_handled('/middleware_exceptions/not_found/', ['Test Request Exception'])
    477546
    478547        # Check that the right middleware methods have been invoked
    479         self.assert_middleware_usage(pre_middleware,  True,  False, True, False)
    480         self.assert_middleware_usage(bad_middleware,  True,  False, True, False)
    481         self.assert_middleware_usage(post_middleware, False, False, True, False)
     548        self.assert_middleware_usage(pre_middleware,  True,  False, False, True, False)
     549        self.assert_middleware_usage(bad_middleware,  True,  False, False, True, False)
     550        self.assert_middleware_usage(post_middleware, False, False, False, True, False)
    482551
    483552    def test_process_view_bad_middleware_not_found(self):
    484553        pre_middleware = TestMiddleware()
     
    490559        self.assert_exceptions_handled('/middleware_exceptions/not_found/', ['Test View Exception'])
    491560
    492561        # Check that the right middleware methods have been invoked
    493         self.assert_middleware_usage(pre_middleware,  True,  True, True, False)
    494         self.assert_middleware_usage(bad_middleware,  True,  True, True, False)
    495         self.assert_middleware_usage(post_middleware, True, False, True, False)
     562        self.assert_middleware_usage(pre_middleware,  True, True,  False, True, False)
     563        self.assert_middleware_usage(bad_middleware,  True, True,  False, True, False)
     564        self.assert_middleware_usage(post_middleware, True, False, False, True, False)
    496565
    497566    def test_process_response_bad_middleware_not_found(self):
    498567        pre_middleware = TestMiddleware()
     
    504573        self.assert_exceptions_handled('/middleware_exceptions/not_found/', ['Test Response Exception'])
    505574
    506575        # Check that the right middleware methods have been invoked
    507         self.assert_middleware_usage(pre_middleware,  True,  True, False, True)
    508         self.assert_middleware_usage(bad_middleware,  True,  True, True,  True)
    509         self.assert_middleware_usage(post_middleware, True,  True, True,  True)
     576        self.assert_middleware_usage(pre_middleware,  True, True, False, False, True)
     577        self.assert_middleware_usage(bad_middleware,  True, True, False, True,  True)
     578        self.assert_middleware_usage(post_middleware, True, True, False, True,  True)
    510579
    511580    def test_process_exception_bad_middleware_not_found(self):
    512581        pre_middleware = TestMiddleware()
     
    518587        self.assert_exceptions_handled('/middleware_exceptions/not_found/', ['Test Exception Exception'])
    519588
    520589        # Check that the right middleware methods have been invoked
    521         self.assert_middleware_usage(pre_middleware,  True,  True, True, False)
    522         self.assert_middleware_usage(bad_middleware,  True,  True,  True, True)
    523         self.assert_middleware_usage(post_middleware, True,  True,  True, True)
     590        self.assert_middleware_usage(pre_middleware,  True, True, False, True, False)
     591        self.assert_middleware_usage(bad_middleware,  True, True, False, True, True)
     592        self.assert_middleware_usage(post_middleware, True, True, False, True, True)
    524593
    525594    def test_process_request_bad_middleware_exception(self):
    526595        pre_middleware = TestMiddleware()
     
    532601        self.assert_exceptions_handled('/middleware_exceptions/error/', ['Test Request Exception'])
    533602
    534603        # Check that the right middleware methods have been invoked
    535         self.assert_middleware_usage(pre_middleware,  True,  False, True, False)
    536         self.assert_middleware_usage(bad_middleware,  True,  False, True, False)
    537         self.assert_middleware_usage(post_middleware, False, False, True, False)
     604        self.assert_middleware_usage(pre_middleware,  True,  False, False, True, False)
     605        self.assert_middleware_usage(bad_middleware,  True,  False, False, True, False)
     606        self.assert_middleware_usage(post_middleware, False, False, False, True, False)
    538607
    539608    def test_process_view_bad_middleware_exception(self):
    540609        pre_middleware = TestMiddleware()
     
    546615        self.assert_exceptions_handled('/middleware_exceptions/error/', ['Test View Exception'])
    547616
    548617        # Check that the right middleware methods have been invoked
    549         self.assert_middleware_usage(pre_middleware,  True,  True, True, False)
    550         self.assert_middleware_usage(bad_middleware,  True,  True, True, False)
    551         self.assert_middleware_usage(post_middleware, True, False, True, False)
     618        self.assert_middleware_usage(pre_middleware,  True, True,  False, True, False)
     619        self.assert_middleware_usage(bad_middleware,  True, True,  False, True, False)
     620        self.assert_middleware_usage(post_middleware, True, False, False, True, False)
    552621
    553622    def test_process_response_bad_middleware_exception(self):
    554623        pre_middleware = TestMiddleware()
     
    560629        self.assert_exceptions_handled('/middleware_exceptions/error/', ['Error in view', 'Test Response Exception'])
    561630
    562631        # Check that the right middleware methods have been invoked
    563         self.assert_middleware_usage(pre_middleware,  True,  True, False, True)
    564         self.assert_middleware_usage(bad_middleware,  True,  True, True,  True)
    565         self.assert_middleware_usage(post_middleware, True,  True, True,  True)
     632        self.assert_middleware_usage(pre_middleware,  True, True, False, False, True)
     633        self.assert_middleware_usage(bad_middleware,  True, True, False, True,  True)
     634        self.assert_middleware_usage(post_middleware, True, True, False, True,  True)
    566635
    567636    def test_process_exception_bad_middleware_exception(self):
    568637        pre_middleware = TestMiddleware()
     
    574643        self.assert_exceptions_handled('/middleware_exceptions/error/', ['Test Exception Exception'])
    575644
    576645        # Check that the right middleware methods have been invoked
    577         self.assert_middleware_usage(pre_middleware,  True,  True, True, False)
    578         self.assert_middleware_usage(bad_middleware,  True,  True,  True, True)
    579         self.assert_middleware_usage(post_middleware, True,  True,  True, True)
     646        self.assert_middleware_usage(pre_middleware,  True, True, False, True, False)
     647        self.assert_middleware_usage(bad_middleware,  True, True, False, True, True)
     648        self.assert_middleware_usage(post_middleware, True, True, False, True, True)
    580649
    581650    def test_process_request_bad_middleware_null_view(self):
    582651        pre_middleware = TestMiddleware()
     
    588657        self.assert_exceptions_handled('/middleware_exceptions/null_view/', ['Test Request Exception'])
    589658
    590659        # Check that the right middleware methods have been invoked
    591         self.assert_middleware_usage(pre_middleware,  True,  False, True, False)
    592         self.assert_middleware_usage(bad_middleware,  True,  False, True, False)
    593         self.assert_middleware_usage(post_middleware, False, False, True, False)
     660        self.assert_middleware_usage(pre_middleware,  True,  False, False, True, False)
     661        self.assert_middleware_usage(bad_middleware,  True,  False, False, True, False)
     662        self.assert_middleware_usage(post_middleware, False, False, False, True, False)
    594663
    595664    def test_process_view_bad_middleware_null_view(self):
    596665        pre_middleware = TestMiddleware()
     
    602671        self.assert_exceptions_handled('/middleware_exceptions/null_view/', ['Test View Exception'])
    603672
    604673        # Check that the right middleware methods have been invoked
    605         self.assert_middleware_usage(pre_middleware,  True,  True, True, False)
    606         self.assert_middleware_usage(bad_middleware,  True,  True, True, False)
    607         self.assert_middleware_usage(post_middleware, True, False, True, False)
     674        self.assert_middleware_usage(pre_middleware,  True, True,  False, True, False)
     675        self.assert_middleware_usage(bad_middleware,  True, True,  False, True, False)
     676        self.assert_middleware_usage(post_middleware, True, False, False, True, False)
    608677
    609678    def test_process_response_bad_middleware_null_view(self):
    610679        pre_middleware = TestMiddleware()
     
    619688            ])
    620689
    621690        # Check that the right middleware methods have been invoked
    622         self.assert_middleware_usage(pre_middleware,  True,  True, False, False)
    623         self.assert_middleware_usage(bad_middleware,  True,  True, True,  False)
    624         self.assert_middleware_usage(post_middleware, True,  True, True,  False)
     691        self.assert_middleware_usage(pre_middleware,  True, True, False, False, False)
     692        self.assert_middleware_usage(bad_middleware,  True, True, False, True,  False)
     693        self.assert_middleware_usage(post_middleware, True, True, False, True,  False)
    625694
    626695    def test_process_exception_bad_middleware_null_view(self):
    627696        pre_middleware = TestMiddleware()
     
    636705            ValueError())
    637706
    638707        # Check that the right middleware methods have been invoked
    639         self.assert_middleware_usage(pre_middleware,  True,  True, True, False)
    640         self.assert_middleware_usage(bad_middleware,  True,  True, True, False)
    641         self.assert_middleware_usage(post_middleware, True,  True, True, False)
     708        self.assert_middleware_usage(pre_middleware,  True, True, False, True, False)
     709        self.assert_middleware_usage(bad_middleware,  True, True, False, True, False)
     710        self.assert_middleware_usage(post_middleware, True, True, False, True, False)
    642711
    643712    def test_process_request_bad_middleware_permission_denied(self):
    644713        pre_middleware = TestMiddleware()
     
    650719        self.assert_exceptions_handled('/middleware_exceptions/permission_denied/', ['Test Request Exception'])
    651720
    652721        # Check that the right middleware methods have been invoked
    653         self.assert_middleware_usage(pre_middleware,  True,  False, True, False)
    654         self.assert_middleware_usage(bad_middleware,  True,  False, True, False)
    655         self.assert_middleware_usage(post_middleware, False, False, True, False)
     722        self.assert_middleware_usage(pre_middleware,  True,  False, False, True, False)
     723        self.assert_middleware_usage(bad_middleware,  True,  False, False, True, False)
     724        self.assert_middleware_usage(post_middleware, False, False, False, True, False)
    656725
    657726    def test_process_view_bad_middleware_permission_denied(self):
    658727        pre_middleware = TestMiddleware()
     
    664733        self.assert_exceptions_handled('/middleware_exceptions/permission_denied/', ['Test View Exception'])
    665734
    666735        # Check that the right middleware methods have been invoked
    667         self.assert_middleware_usage(pre_middleware,  True,  True, True, False)
    668         self.assert_middleware_usage(bad_middleware,  True,  True, True, False)
    669         self.assert_middleware_usage(post_middleware, True, False, True, False)
     736        self.assert_middleware_usage(pre_middleware,  True, True,  False, True, False)
     737        self.assert_middleware_usage(bad_middleware,  True, True,  False, True, False)
     738        self.assert_middleware_usage(post_middleware, True, False, False, True, False)
    670739
    671740    def test_process_response_bad_middleware_permission_denied(self):
    672741        pre_middleware = TestMiddleware()
     
    678747        self.assert_exceptions_handled('/middleware_exceptions/permission_denied/', ['Test Response Exception'])
    679748
    680749        # Check that the right middleware methods have been invoked
    681         self.assert_middleware_usage(pre_middleware,  True,  True, False, True)
    682         self.assert_middleware_usage(bad_middleware,  True,  True, True,  True)
    683         self.assert_middleware_usage(post_middleware, True,  True, True,  True)
     750        self.assert_middleware_usage(pre_middleware,  True, True, False, False, True)
     751        self.assert_middleware_usage(bad_middleware,  True, True, False, True,  True)
     752        self.assert_middleware_usage(post_middleware, True, True, False, True,  True)
    684753
    685754    def test_process_exception_bad_middleware_permission_denied(self):
    686755        pre_middleware = TestMiddleware()
     
    692761        self.assert_exceptions_handled('/middleware_exceptions/permission_denied/', ['Test Exception Exception'])
    693762
    694763        # Check that the right middleware methods have been invoked
    695         self.assert_middleware_usage(pre_middleware,  True,  True, True, False)
    696         self.assert_middleware_usage(bad_middleware,  True,  True,  True, True)
    697         self.assert_middleware_usage(post_middleware, True,  True,  True, True)
     764        self.assert_middleware_usage(pre_middleware,  True, True, False, True, False)
     765        self.assert_middleware_usage(bad_middleware,  True, True, False, True, True)
     766        self.assert_middleware_usage(post_middleware, True, True, False, True, True)
    698767
    699768
    700769_missing = object()
  • tests/regressiontests/middleware_exceptions/urls.py

    diff -r 78ad3faa689b tests/regressiontests/middleware_exceptions/urls.py
    a b  
    99    (r'^error/$', views.server_error),
    1010    (r'^null_view/$', views.null_view),
    1111    (r'^permission_denied/$', views.permission_denied),
     12
     13    (r'^template_response/$', views.template_response),
     14    (r'^template_response_error/$', views.template_response_error),
    1215)
  • tests/regressiontests/middleware_exceptions/views.py

    diff -r 78ad3faa689b tests/regressiontests/middleware_exceptions/views.py
    a b  
    11from django import http
    22from django.core.exceptions import PermissionDenied
     3from django.shortcuts import render
     4from django.template import Template
    35
    46def normal_view(request):
    57    return http.HttpResponse('OK')
    68
     9def template_response(request):
     10    return render(request, Template('OK'))
     11
     12def template_response_error(request):
     13    return render(request, Template('{%'))
     14
    715def not_found(request):
    816    raise http.Http404()
    917
  • new file tests/regressiontests/templates/response.py

    diff -r 78ad3faa689b tests/regressiontests/templates/response.py
    - +  
     1import os
     2from django.utils import unittest
     3from django.test import RequestFactory
     4from django.conf import settings
     5import django.template.context
     6from django.template import Template, Context, RequestContext
     7from django.template.response import (TemplateResponse, SimpleTemplateResponse,
     8                                      ContentNotBakedError)
     9
     10def test_processor(request):
     11    return {'processors': 'yes'}
     12test_processor_name = 'regressiontests.templates.response.test_processor'
     13
     14class BaseTemplateResponseTest(unittest.TestCase):
     15    # tests rely on fact that global context
     16    # processors should only work when RequestContext is used.
     17
     18    def setUp(self):
     19        self.factory = RequestFactory()
     20        self._old_processors = settings.TEMPLATE_CONTEXT_PROCESSORS
     21        self._old_TEMPLATE_DIRS = settings.TEMPLATE_DIRS
     22        settings.TEMPLATE_CONTEXT_PROCESSORS = [test_processor_name]
     23        settings.TEMPLATE_DIRS = (
     24            os.path.join(
     25                os.path.dirname(__file__),
     26                'templates'
     27            ),
     28        )
     29        # Force re-evaluation of the contex processor list
     30        django.template.context._standard_context_processors = None
     31
     32    def tearDown(self):
     33        settings.TEMPLATE_DIRS = self._old_TEMPLATE_DIRS
     34        settings.TEMPLATE_CONTEXT_PROCESSORS = self._old_processors
     35        # Force re-evaluation of the contex processor list
     36        django.template.context._standard_context_processors = None
     37
     38
     39class SimpleTemplateResponseTest(BaseTemplateResponseTest):
     40
     41    def _response(self, template='foo', *args, **kwargs):
     42        return SimpleTemplateResponse(Template(template), *args, **kwargs)
     43
     44    def test_template_resolving(self):
     45        response = SimpleTemplateResponse('first/test.html')
     46        response.bake()
     47        self.assertEqual('First template\n', response.content)
     48
     49        templates = ['foo.html', 'second/test.html', 'first/test.html']
     50        response = SimpleTemplateResponse(templates)
     51        response.bake()
     52        self.assertEqual('Second template\n', response.content)
     53
     54        response = self._response()
     55        response.bake()
     56        self.assertEqual(response.content, 'foo')
     57
     58    def test_explicit_baking(self):
     59        # explicit baking
     60        response = self._response()
     61        self.assertFalse(response.baked)
     62        response.bake()
     63        self.assertTrue(response.baked)
     64
     65    def test_bake(self):
     66        # response is not re-baked without the bake call
     67        response = self._response().bake()
     68        self.assertEqual(response.content, 'foo')
     69
     70        # rebaking doesn't change the baked content
     71        response.template_name = Template('bar{{ baz }}')
     72        response.bake()
     73        self.assertEqual(response.content, 'foo')
     74
     75        # but baked content can be overridden by manually
     76        # setting content
     77        response.content = 'bar'
     78        self.assertEqual(response.content, 'bar')
     79
     80    def test_iteration_unbaked(self):
     81        # unbaked response raises an exception on iteration
     82        response = self._response()
     83        self.assertFalse(response.baked)
     84
     85        def iteration():
     86            for x in response:
     87                pass
     88        self.assertRaises(ContentNotBakedError, iteration)
     89        self.assertFalse(response.baked)
     90
     91    def test_iteration_baked(self):
     92        # iteration works for baked responses
     93        response = self._response().bake()
     94        res = [x for x in response]
     95        self.assertEqual(res, ['foo'])
     96
     97    def test_content_access_unbaked(self):
     98        # unbaked response raises an exception when content is accessed
     99        response = self._response()
     100        self.assertFalse(response.baked)
     101        self.assertRaises(ContentNotBakedError, lambda: response.content)
     102        self.assertFalse(response.baked)
     103
     104    def test_content_access_baked(self):
     105        # baked response content can be accessed
     106        response = self._response().bake()
     107        self.assertEqual(response.content, 'foo')
     108
     109    def test_set_content(self):
     110        # content can be overriden
     111        response = self._response()
     112        self.assertFalse(response.baked)
     113        response.content = 'spam'
     114        self.assertTrue(response.baked)
     115        self.assertEqual(response.content, 'spam')
     116        response.content = 'baz'
     117        self.assertEqual(response.content, 'baz')
     118
     119    def test_dict_context(self):
     120        response = self._response('{{ foo }}{{ processors }}',
     121                                  {'foo': 'bar'})
     122        self.assertEqual(response.context_data, {'foo': 'bar'})
     123        response.bake()
     124        self.assertEqual(response.content, 'bar')
     125
     126    def test_context_instance(self):
     127        response = self._response('{{ foo }}{{ processors }}',
     128                                  Context({'foo': 'bar'}))
     129        self.assertEqual(response.context_data.__class__, Context)
     130        response.bake()
     131        self.assertEqual(response.content, 'bar')
     132
     133    def test_kwargs(self):
     134        response = self._response(content_type = 'application/json', status=504)
     135        self.assertEqual(response['content-type'], 'application/json')
     136        self.assertEqual(response.status_code, 504)
     137
     138    def test_args(self):
     139        response = SimpleTemplateResponse('', {}, 'application/json', 504)
     140        self.assertEqual(response['content-type'], 'application/json')
     141        self.assertEqual(response.status_code, 504)
     142
     143
     144class TemplateResponseTest(BaseTemplateResponseTest):
     145
     146    def _response(self, template='foo', *args, **kwargs):
     147        return TemplateResponse(self.factory.get('/'), Template(template),
     148                                *args, **kwargs)
     149
     150    def test_render(self):
     151        response = self._response('{{ foo }}{{ processors }}').bake()
     152        self.assertEqual(response.content, 'yes')
     153
     154    def test_render_with_requestcontext(self):
     155        response = self._response('{{ foo }}{{ processors }}',
     156                                  {'foo': 'bar'}).bake()
     157        self.assertEqual(response.content, 'baryes')
     158
     159    def test_render_with_context(self):
     160        response = self._response('{{ foo }}{{ processors }}',
     161                                  Context({'foo': 'bar'})).bake()
     162        self.assertEqual(response.content, 'bar')
     163
     164    def test_kwargs(self):
     165        response = self._response(content_type = 'application/json',
     166                                  status=504)
     167        self.assertEqual(response['content-type'], 'application/json')
     168        self.assertEqual(response.status_code, 504)
     169
     170    def test_args(self):
     171        response = TemplateResponse(self.factory.get('/'), '', {},
     172                                    'application/json', 504)
     173        self.assertEqual(response['content-type'], 'application/json')
     174        self.assertEqual(response.status_code, 504)
  • tests/regressiontests/templates/tests.py

    diff -r 78ad3faa689b tests/regressiontests/templates/tests.py
    a b  
    2828from unicode import UnicodeTests
    2929from nodelist import NodelistTest
    3030from smartif import *
     31from response import *
    3132
    3233try:
    3334    from loaders import *
  • new file tests/regressiontests/views/templates/debug/render_test.html

    diff -r 78ad3faa689b tests/regressiontests/views/templates/debug/render_test.html
    - +  
     1{{ foo }}.{{ bar }}.{{ baz }}.{{ processors }}
  • tests/regressiontests/views/tests/__init__.py

    diff -r 78ad3faa689b tests/regressiontests/views/tests/__init__.py
    a b  
    77from i18n import *
    88from specials import *
    99from static import *
     10from shortcuts import *
  • new file tests/regressiontests/views/tests/shortcuts.py

    diff -r 78ad3faa689b tests/regressiontests/views/tests/shortcuts.py
    - +  
     1from django.test import RequestFactory
     2from django.template import Template
     3from django.shortcuts import render
     4
     5from regressiontests.templates.response import BaseTemplateResponseTest
     6
     7def test_view(request):
     8    return render(request, 'debug/render_test.html',
     9                  {'foo': 'foo', 'baz': 'baz'})
     10
     11
     12class RenderTest(BaseTemplateResponseTest):
     13
     14    def setUp(self):
     15        super(RenderTest, self).setUp()
     16        self.request = self.factory.get('/')
     17
     18    def test_simple_view(self):
     19        response = test_view(self.request)
     20        self.assertEqual(response.content, 'foo..baz.yes\n')
Back to Top