Ticket #15010: template-response-current_app.patch

File template-response-current_app.patch, 12.7 KB (added by Chris Adams, 14 years ago)
  • django/template/response.py

    From 18bb674234e836ba3a8aa6b63c9001100a03b7d0 Mon Sep 17 00:00:00 2001
    From: Chris Adams <chris@improbable.org>
    Date: Mon, 3 Jan 2011 11:57:26 -0500
    Subject: [PATCH 1/5] TemplateResponse: accept a current_app parameter for RequestContext
    
    This simplifies cases such as the Django admin conversion in #15008 where the
    need to set current_app requires an extra import and creating the RequestContext
    manually.
    ---
     django/template/response.py                 |    7 +++++--
     tests/regressiontests/templates/response.py |    7 +++++++
     2 files changed, 12 insertions(+), 2 deletions(-)
    
    diff --git a/django/template/response.py b/django/template/response.py
    index d89fee0..629461a 100644
    a b class SimpleTemplateResponse(HttpResponse):  
    9090
    9191class TemplateResponse(SimpleTemplateResponse):
    9292    def __init__(self, request, template, context=None, mimetype=None,
    93             status=None, content_type=None):
     93            status=None, content_type=None, current_app=None):
    9494        # self.request gets over-written by django.test.client.Client - and
    9595        # unlike context_data and template_name the _request should not
    9696        # be considered part of the public API.
    9797        self._request = request
     98        # As a convenience we'll allow callers to provide current_app without
     99        # having to avoid needing to create the RequestContext directly
     100        self._current_app = current_app
    98101        super(TemplateResponse, self).__init__(
    99102            template, context, mimetype, status, content_type)
    100103
    class TemplateResponse(SimpleTemplateResponse):  
    105108        if isinstance(context, Context):
    106109            return context
    107110        else:
    108             return RequestContext(self._request, context)
     111            return RequestContext(self._request, context, current_app=self._current_app)
  • tests/regressiontests/templates/response.py

    diff --git a/tests/regressiontests/templates/response.py b/tests/regressiontests/templates/response.py
    index 8bdf7f4..2f0d2c7 100644
    a b class TemplateResponseTest(BaseTemplateResponseTest):  
    172172                                    'application/json', 504)
    173173        self.assertEqual(response['content-type'], 'application/json')
    174174        self.assertEqual(response.status_code, 504)
     175
     176    def test_custom_app(self):
     177        response = self._response('{{ foo }}', current_app="foobar")
     178
     179        rc = response.resolve_context(response.context_data)
     180
     181        self.assertEqual(rc.current_app, 'foobar')
  • django/shortcuts/__init__.py

    -- 
    1.7.0.2
    
    
    From fc912c9def744d5a504db15a8061610eee899597 Mon Sep 17 00:00:00 2001
    From: Chris Adams <chris@improbable.org>
    Date: Mon, 3 Jan 2011 21:33:30 -0500
    Subject: [PATCH 2/5] Add current_app support to shortcuts.render
    
    This parallels the earlier change to TemplateResponse, providing a convenient way to pass current_app without having to instantiate a RequestContext by hand.
    
    See http://code.djangoproject.com/ticket/15010
    ---
     django/shortcuts/__init__.py                   |   10 +++++++++-
     tests/regressiontests/views/tests/shortcuts.py |    4 ++++
     tests/regressiontests/views/urls.py            |    2 +-
     tests/regressiontests/views/views.py           |    6 ++++++
     4 files changed, 20 insertions(+), 2 deletions(-)
    
    diff --git a/django/shortcuts/__init__.py b/django/shortcuts/__init__.py
    index b7d69b5..6347d3f 100644
    a b def render(request, *args, **kwargs):  
    2929        'content_type': kwargs.pop('content_type', None),
    3030        'status': kwargs.pop('status', None),
    3131    }
    32     kwargs['context_instance'] = kwargs.get('context_instance', RequestContext(request))
     32
     33    if 'context_instance' in kwargs:
     34        context_instance = kwargs.pop("context_instance")
     35    else:
     36        current_app = kwargs.pop("current_app", None)
     37        context_instance = RequestContext(request, current_app=current_app)
     38
     39    kwargs['context_instance'] = context_instance
     40
    3341    return HttpResponse(loader.render_to_string(*args, **kwargs),
    3442                        **httpresponse_kwargs)
    3543
  • tests/regressiontests/views/tests/shortcuts.py

    diff --git a/tests/regressiontests/views/tests/shortcuts.py b/tests/regressiontests/views/tests/shortcuts.py
    index 3f260fe..fa8408c 100644
    a b class ShortcutTests(TestCase):  
    5656        self.assertEquals(response.status_code, 403)
    5757        self.assertEquals(response.content, 'FOO.BAR../path/to/static/media\n')
    5858
     59    def test_render_with_current_app(self):
     60        response = self.client.get('/views/shortcuts/render/current_app/')
     61        self.assertEquals(response.context.current_app, "foobar_app")
     62
  • tests/regressiontests/views/urls.py

    diff --git a/tests/regressiontests/views/urls.py b/tests/regressiontests/views/urls.py
    index 7cba5f6..7dad098 100644
    a b urlpatterns += patterns('regressiontests.views.views',  
    151151    (r'^shortcuts/render/base_context/$', 'render_view_with_base_context'),
    152152    (r'^shortcuts/render/content_type/$', 'render_view_with_content_type'),
    153153    (r'^shortcuts/render/status/$', 'render_view_with_status'),
    154 
     154    (r'^shortcuts/render/current_app/$', 'render_view_with_current_app'),
    155155)
    156156
    157157# simple generic views.
  • tests/regressiontests/views/views.py

    diff --git a/tests/regressiontests/views/views.py b/tests/regressiontests/views/views.py
    index ec017bd..9c9b4c5 100644
    a b def render_view_with_status(request):  
    101101        'foo': 'FOO',
    102102        'bar': 'BAR',
    103103    }, status=403)
     104
     105def render_view_with_current_app(request):
     106    return render(request, 'debug/render_test.html', {
     107        'foo': 'FOO',
     108        'bar': 'BAR',
     109    }, current_app="foobar_app")
  • docs/ref/template-response.txt

    -- 
    1.7.0.2
    
    
    From d1024ace8965230d5eac7d2a7a8cefeeefc3b36d Mon Sep 17 00:00:00 2001
    From: Chris Adams <chris@improbable.org>
    Date: Mon, 3 Jan 2011 21:46:51 -0500
    Subject: [PATCH 3/5] Documentation for current_app on render shortcut and TemplateResponse
    
    Basic documentation and a pointer to the namespaced URL resolution strategy.
    ---
     docs/ref/template-response.txt |    7 ++++++-
     docs/topics/http/shortcuts.txt |    9 +++++++--
     2 files changed, 13 insertions(+), 3 deletions(-)
    
    diff --git a/docs/ref/template-response.txt b/docs/ref/template-response.txt
    index 3b136b6..d4fe2c4 100644
    a b TemplateResponse objects  
    129129Methods
    130130-------
    131131
    132 .. method:: TemplateResponse.__init__(request, template, context=None, mimetype=None, status=None, content_type=None)
     132.. method:: TemplateResponse.__init__(request, template, context=None, mimetype=None, status=None, content_type=None, current_app=None)
    133133
    134134    Instantiates an ``TemplateResponse`` object with the given
    135135    template, context, MIME type and HTTP status.
    Methods  
    158158        ``content_type`` is used. If neither is given,
    159159        :setting:`DEFAULT_CONTENT_TYPE` is used.
    160160
     161    ``current_app``
     162        A hint indicating which application contains the current view. See the
     163        :ref:`namespaced URL resolution strategy <topics-http-reversing-url-namespaces>`
     164        for more information.
     165
    161166
    162167The rendering process
    163168=====================
  • docs/topics/http/shortcuts.txt

    diff --git a/docs/topics/http/shortcuts.txt b/docs/topics/http/shortcuts.txt
    index 1c1dc9e..9d72521 100644
    a b introduce controlled coupling for convenience's sake.  
    1515``render``
    1616==========
    1717
    18 .. function:: render(request, template[, dictionary][, context_instance][, content_type][, status])
     18.. function:: render(request, template[, dictionary][, context_instance][, content_type][, status][, current_app])
    1919
    2020   .. versionadded:: 1.3
    2121
    introduce controlled coupling for convenience's sake.  
    2323   :class:`~django.http.HttpResponse` object with that rendered text.
    2424
    2525   :func:`render()` is the same as a call to
    26    :func:`render_to_response()` with a context_instance argument that
     26   :func:`render_to_response()` with a `context_instance` argument that
    2727   that forces the use of a :class:`RequestContext`.
    2828
    2929Required arguments
    Optional arguments  
    5555``status``
    5656    The status code for the response. Defaults to ``200``.
    5757
     58``current_app``
     59    A hint indicating which application contains the current view. See the
     60    :ref:`namespaced URL resolution strategy <topics-http-reversing-url-namespaces>`
     61    for more information.
     62
    5863Example
    5964-------
    6065
  • django/shortcuts/__init__.py

    -- 
    1.7.0.2
    
    
    From 3525c20f5c7375c3ab13b5a509b0be6c588a0254 Mon Sep 17 00:00:00 2001
    From: Chris Adams <chris@improbable.org>
    Date: Mon, 3 Jan 2011 22:05:13 -0500
    Subject: [PATCH 4/5] render(): Added a simple current_app sanity check
    
    This enforces a simple policy: render() will only set current_app on
    RequestContexts which it creates.
    ---
     django/shortcuts/__init__.py                   |    2 ++
     tests/regressiontests/views/tests/shortcuts.py |    3 +++
     tests/regressiontests/views/urls.py            |    1 +
     tests/regressiontests/views/views.py           |    8 ++++++++
     4 files changed, 14 insertions(+), 0 deletions(-)
    
    diff --git a/django/shortcuts/__init__.py b/django/shortcuts/__init__.py
    index 6347d3f..98116f0 100644
    a b def render(request, *args, **kwargs):  
    3232
    3333    if 'context_instance' in kwargs:
    3434        context_instance = kwargs.pop("context_instance")
     35        if kwargs.get("current_app", None):
     36            raise ValueError("If you provide a context_instance you must set its current_app before calling render()")
    3537    else:
    3638        current_app = kwargs.pop("current_app", None)
    3739        context_instance = RequestContext(request, current_app=current_app)
  • tests/regressiontests/views/tests/shortcuts.py

    diff --git a/tests/regressiontests/views/tests/shortcuts.py b/tests/regressiontests/views/tests/shortcuts.py
    index fa8408c..c974348 100644
    a b class ShortcutTests(TestCase):  
    6060        response = self.client.get('/views/shortcuts/render/current_app/')
    6161        self.assertEquals(response.context.current_app, "foobar_app")
    6262
     63    def test_render_with_current_app_conflict(self):
     64        self.assertRaises(ValueError, self.client.get, '/views/shortcuts/render/current_app_conflict/')
     65
  • tests/regressiontests/views/urls.py

    diff --git a/tests/regressiontests/views/urls.py b/tests/regressiontests/views/urls.py
    index 7dad098..a170efb 100644
    a b urlpatterns += patterns('regressiontests.views.views',  
    152152    (r'^shortcuts/render/content_type/$', 'render_view_with_content_type'),
    153153    (r'^shortcuts/render/status/$', 'render_view_with_status'),
    154154    (r'^shortcuts/render/current_app/$', 'render_view_with_current_app'),
     155    (r'^shortcuts/render/current_app_conflict/$', 'render_view_with_current_app_conflict'),
    155156)
    156157
    157158# simple generic views.
  • tests/regressiontests/views/views.py

    diff --git a/tests/regressiontests/views/views.py b/tests/regressiontests/views/views.py
    index 9c9b4c5..e4e7c3d 100644
    a b def render_view_with_current_app(request):  
    107107        'foo': 'FOO',
    108108        'bar': 'BAR',
    109109    }, current_app="foobar_app")
     110
     111def render_view_with_current_app_conflict(request):
     112    # This should fail because we don't passing both a current_app and
     113    # context_instance:
     114    return render(request, 'debug/render_test.html', {
     115        'foo': 'FOO',
     116        'bar': 'BAR',
     117    }, current_app="foobar_app", context_instance=RequestContext(request))
  • tests/regressiontests/views/tests/shortcuts.py

    -- 
    1.7.0.2
    
    
    From 67b08c22bffeb7ab4014fa22b99a67f3c684240e Mon Sep 17 00:00:00 2001
    From: Chris Adams <chris@improbable.org>
    Date: Mon, 3 Jan 2011 22:13:48 -0500
    Subject: [PATCH 5/5] shortcuts.render(): test update
    
    * Add positive assertion that current_app is not accidentally set
    ---
     tests/regressiontests/views/tests/shortcuts.py |    1 +
     1 files changed, 1 insertions(+), 0 deletions(-)
    
    diff --git a/tests/regressiontests/views/tests/shortcuts.py b/tests/regressiontests/views/tests/shortcuts.py
    index c974348..c5f664e 100644
    a b class ShortcutTests(TestCase):  
    3838        self.assertEquals(response.status_code, 200)
    3939        self.assertEquals(response.content, 'FOO.BAR../path/to/static/media\n')
    4040        self.assertEquals(response['Content-Type'], 'text/html; charset=utf-8')
     41        self.assertEquals(response.context.current_app, None)
    4142
    4243    def test_render_with_base_context(self):
    4344        response = self.client.get('/views/shortcuts/render/base_context/')
Back to Top