Fixed #8092, #3828 -- Removed dictionary access for request objects so that GET and POST data doesn't "overwrite" request attributes when used in templates (since dictionary lookup is performed before attribute lookup). This is backwards-incompatible if you were using the request object for dictionary access to the combined GET and POST data, but you should use `request.REQUEST` for that instead.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@8202 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Gary Wilson Jr 2008-08-03 19:55:26 +00:00
parent 71b2e01ec2
commit daa6b38f35
8 changed files with 68 additions and 23 deletions

View File

@ -39,17 +39,6 @@ class HttpRequest(object):
(pformat(self.GET), pformat(self.POST), pformat(self.COOKIES),
pformat(self.META))
def __getitem__(self, key):
for d in (self.POST, self.GET):
if key in d:
return d[key]
raise KeyError, "%s not found in either POST or GET" % key
def has_key(self, key):
return key in self.GET or key in self.POST
__contains__ = has_key
def get_host(self):
"""Returns the HTTP host using the environment or request headers."""
# We try three options, in order of decreasing preference.

View File

@ -170,18 +170,6 @@ All attributes except ``session`` should be considered read-only.
Methods
-------
``__getitem__(key)``
Returns the GET/POST value for the given key, checking POST first, then
GET. Raises ``KeyError`` if the key doesn't exist.
This lets you use dictionary-accessing syntax on an ``HttpRequest``
instance. Example: ``request["foo"]`` would return ``True`` if either
``request.POST`` or ``request.GET`` had a ``"foo"`` key.
``has_key()``
Returns ``True`` or ``False``, designating whether ``request.GET`` or
``request.POST`` has the given key.
``get_host()``
**New in Django development version**

View File

@ -0,0 +1 @@
# Models file for tests to run.

View File

@ -0,0 +1,13 @@
{% if request %}
Have request
{% else %}
No request
{% endif %}
{% if request.is_secure %}
Secure
{% else %}
Not secure
{% endif %}
{{ request.path }}

View File

@ -0,0 +1,38 @@
"""
Tests for Django's bundled context processors.
"""
from django.conf import settings
from django.test import TestCase
class RequestContextProcessorTests(TestCase):
"""
Tests for the ``django.core.context_processors.request`` processor.
"""
urls = 'regressiontests.context_processors.urls'
def test_request_attributes(self):
"""
Test that the request object is available in the template and that its
attributes can't be overridden by GET and POST parameters (#3828).
"""
url = '/request_attrs/'
# We should have the request object in the template.
response = self.client.get(url)
self.assertContains(response, 'Have request')
# Test is_secure.
response = self.client.get(url)
self.assertContains(response, 'Not secure')
response = self.client.get(url, {'is_secure': 'blah'})
self.assertContains(response, 'Not secure')
response = self.client.post(url, {'is_secure': 'blah'})
self.assertContains(response, 'Not secure')
# Test path.
response = self.client.get(url)
self.assertContains(response, url)
response = self.client.get(url, {'path': '/blah/'})
self.assertContains(response, url)
response = self.client.post(url, {'path': '/blah/'})
self.assertContains(response, url)

View File

@ -0,0 +1,8 @@
from django.conf.urls.defaults import *
import views
urlpatterns = patterns('',
(r'^request_attrs/$', views.request_processor),
)

View File

@ -0,0 +1,8 @@
from django.core import context_processors
from django.shortcuts import render_to_response
from django.template.context import RequestContext
def request_processor(request):
return render_to_response('context_processors/request_attrs.html',
RequestContext(request, {}, processors=[context_processors.request]))