Fixed #18659 -- Deprecated request.REQUEST and MergeDict
Thanks Aymeric Augustin for the suggestion.
This commit is contained in:
parent
98788d3c3a
commit
2fb5a51fa3
|
@ -1284,8 +1284,10 @@ class ModelAdmin(BaseModelAdmin):
|
||||||
context = dict(self.admin_site.each_context(),
|
context = dict(self.admin_site.each_context(),
|
||||||
title=_('Add %s') % force_text(opts.verbose_name),
|
title=_('Add %s') % force_text(opts.verbose_name),
|
||||||
adminform=adminForm,
|
adminform=adminForm,
|
||||||
is_popup=IS_POPUP_VAR in request.REQUEST,
|
is_popup=(IS_POPUP_VAR in request.POST or
|
||||||
to_field=request.REQUEST.get(TO_FIELD_VAR),
|
IS_POPUP_VAR in request.GET),
|
||||||
|
to_field=request.POST.get(TO_FIELD_VAR,
|
||||||
|
request.GET.get(TO_FIELD_VAR)),
|
||||||
media=media,
|
media=media,
|
||||||
inline_admin_formsets=inline_admin_formsets,
|
inline_admin_formsets=inline_admin_formsets,
|
||||||
errors=helpers.AdminErrorList(form, formsets),
|
errors=helpers.AdminErrorList(form, formsets),
|
||||||
|
@ -1357,8 +1359,10 @@ class ModelAdmin(BaseModelAdmin):
|
||||||
adminform=adminForm,
|
adminform=adminForm,
|
||||||
object_id=object_id,
|
object_id=object_id,
|
||||||
original=obj,
|
original=obj,
|
||||||
is_popup=IS_POPUP_VAR in request.REQUEST,
|
is_popup=(IS_POPUP_VAR in request.POST or
|
||||||
to_field=request.REQUEST.get(TO_FIELD_VAR),
|
IS_POPUP_VAR in request.GET),
|
||||||
|
to_field=request.POST.get(TO_FIELD_VAR,
|
||||||
|
request.GET.get(TO_FIELD_VAR)),
|
||||||
media=media,
|
media=media,
|
||||||
inline_admin_formsets=inline_admin_formsets,
|
inline_admin_formsets=inline_admin_formsets,
|
||||||
errors=helpers.AdminErrorList(form, formsets),
|
errors=helpers.AdminErrorList(form, formsets),
|
||||||
|
|
|
@ -144,7 +144,8 @@ class UserAdmin(admin.ModelAdmin):
|
||||||
'adminForm': adminForm,
|
'adminForm': adminForm,
|
||||||
'form_url': form_url,
|
'form_url': form_url,
|
||||||
'form': form,
|
'form': form,
|
||||||
'is_popup': IS_POPUP_VAR in request.REQUEST,
|
'is_popup': (IS_POPUP_VAR in request.POST or
|
||||||
|
IS_POPUP_VAR in request.GET),
|
||||||
'add': True,
|
'add': True,
|
||||||
'change': False,
|
'change': False,
|
||||||
'has_delete_permission': False,
|
'has_delete_permission': False,
|
||||||
|
|
|
@ -526,7 +526,6 @@ class LoginTest(AuthViewsTestCase):
|
||||||
req.COOKIES[settings.CSRF_COOKIE_NAME] = token1
|
req.COOKIES[settings.CSRF_COOKIE_NAME] = token1
|
||||||
req.method = "POST"
|
req.method = "POST"
|
||||||
req.POST = {'username': 'testclient', 'password': password, 'csrfmiddlewaretoken': token1}
|
req.POST = {'username': 'testclient', 'password': password, 'csrfmiddlewaretoken': token1}
|
||||||
req.REQUEST = req.POST
|
|
||||||
|
|
||||||
# Use POST request to log in
|
# Use POST request to log in
|
||||||
SessionMiddleware().process_request(req)
|
SessionMiddleware().process_request(req)
|
||||||
|
|
|
@ -28,7 +28,8 @@ def login(request, template_name='registration/login.html',
|
||||||
"""
|
"""
|
||||||
Displays the login form and handles the login action.
|
Displays the login form and handles the login action.
|
||||||
"""
|
"""
|
||||||
redirect_to = request.REQUEST.get(redirect_field_name, '')
|
redirect_to = request.POST.get(redirect_field_name,
|
||||||
|
request.GET.get(redirect_field_name, ''))
|
||||||
|
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
form = authentication_form(request, data=request.POST)
|
form = authentication_form(request, data=request.POST)
|
||||||
|
@ -71,8 +72,10 @@ def logout(request, next_page=None,
|
||||||
if next_page is not None:
|
if next_page is not None:
|
||||||
next_page = resolve_url(next_page)
|
next_page = resolve_url(next_page)
|
||||||
|
|
||||||
if redirect_field_name in request.REQUEST:
|
if (redirect_field_name in request.POST or
|
||||||
next_page = request.REQUEST[redirect_field_name]
|
redirect_field_name in request.GET):
|
||||||
|
next_page = request.POST.get(redirect_field_name,
|
||||||
|
request.GET.get(redirect_field_name))
|
||||||
# Security check -- don't allow redirection to a different host.
|
# Security check -- don't allow redirection to a different host.
|
||||||
if not is_safe_url(url=next_page, host=request.get_host()):
|
if not is_safe_url(url=next_page, host=request.get_host()):
|
||||||
next_page = request.path
|
next_page = request.path
|
||||||
|
|
|
@ -5,6 +5,7 @@ import logging
|
||||||
import sys
|
import sys
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
from threading import Lock
|
from threading import Lock
|
||||||
|
import warnings
|
||||||
|
|
||||||
from django import http
|
from django import http
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
@ -129,6 +130,8 @@ class WSGIRequest(http.HttpRequest):
|
||||||
return content_type, content_params
|
return content_type, content_params
|
||||||
|
|
||||||
def _get_request(self):
|
def _get_request(self):
|
||||||
|
warnings.warn('`request.REQUEST` is deprecated, use `request.GET` or '
|
||||||
|
'`request.POST` instead.', PendingDeprecationWarning, 2)
|
||||||
if not hasattr(self, '_request'):
|
if not hasattr(self, '_request'):
|
||||||
self._request = datastructures.MergeDict(self.POST, self.GET)
|
self._request = datastructures.MergeDict(self.POST, self.GET)
|
||||||
return self._request
|
return self._request
|
||||||
|
|
|
@ -12,6 +12,8 @@ class MergeDict(object):
|
||||||
first occurrence will be used.
|
first occurrence will be used.
|
||||||
"""
|
"""
|
||||||
def __init__(self, *dicts):
|
def __init__(self, *dicts):
|
||||||
|
warnings.warn('`MergeDict` is deprecated, use `dict.update()` '
|
||||||
|
'instead.', PendingDeprecationWarning, 2)
|
||||||
self.dicts = dicts
|
self.dicts = dicts
|
||||||
|
|
||||||
def __bool__(self):
|
def __bool__(self):
|
||||||
|
|
|
@ -24,7 +24,7 @@ def set_language(request):
|
||||||
redirect to the page in the request (the 'next' parameter) without changing
|
redirect to the page in the request (the 'next' parameter) without changing
|
||||||
any state.
|
any state.
|
||||||
"""
|
"""
|
||||||
next = request.REQUEST.get('next')
|
next = request.POST.get('next', request.GET.get('next'))
|
||||||
if not is_safe_url(url=next, host=request.get_host()):
|
if not is_safe_url(url=next, host=request.get_host()):
|
||||||
next = request.META.get('HTTP_REFERER')
|
next = request.META.get('HTTP_REFERER')
|
||||||
if not is_safe_url(url=next, host=request.get_host()):
|
if not is_safe_url(url=next, host=request.get_host()):
|
||||||
|
|
|
@ -469,6 +469,10 @@ these changes.
|
||||||
|
|
||||||
* ``django.forms.get_declared_fields`` will be removed.
|
* ``django.forms.get_declared_fields`` will be removed.
|
||||||
|
|
||||||
|
* The ``WSGIRequest.REQUEST`` property will be removed.
|
||||||
|
|
||||||
|
* The class ``django.utils.datastructures.MergeDict`` will be removed.
|
||||||
|
|
||||||
2.0
|
2.0
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
|
@ -110,6 +110,9 @@ All attributes should be considered read-only, unless stated otherwise below.
|
||||||
|
|
||||||
.. attribute:: HttpRequest.REQUEST
|
.. attribute:: HttpRequest.REQUEST
|
||||||
|
|
||||||
|
.. deprecated:: 1.7
|
||||||
|
Use the more explicit ``GET`` and ``POST`` instead.
|
||||||
|
|
||||||
For convenience, a dictionary-like object that searches ``POST`` first,
|
For convenience, a dictionary-like object that searches ``POST`` first,
|
||||||
then ``GET``. Inspired by PHP's ``$_REQUEST``.
|
then ``GET``. Inspired by PHP's ``$_REQUEST``.
|
||||||
|
|
||||||
|
|
|
@ -639,3 +639,18 @@ deprecated. Use :djadminopt:`--natural-foreign` instead.
|
||||||
|
|
||||||
Similarly, the ``use_natural_keys`` argument for ``serializers.serialize()``
|
Similarly, the ``use_natural_keys`` argument for ``serializers.serialize()``
|
||||||
has been deprecated. Use ``use_natural_foreign_keys`` instead.
|
has been deprecated. Use ``use_natural_foreign_keys`` instead.
|
||||||
|
|
||||||
|
Merging of ``POST`` and ``GET`` arguments into ``WSGIRequest.REQUEST``
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
It was already strongly suggested that you use ``GET`` and ``POST`` instead of
|
||||||
|
``REQUEST``, because the former are more explicit. The property ``REQUEST`` is
|
||||||
|
deprecated and will be removed in Django 1.9.
|
||||||
|
|
||||||
|
``django.utils.datastructures.MergeDict`` class
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
``MergeDict`` exists primarily to support merging ``POST`` and ``GET``
|
||||||
|
arguments into a ``REQUEST`` property on ``WSGIRequest``. To merge
|
||||||
|
dictionaries, use ``dict.update()`` instead. The class ``MergeDict`` is
|
||||||
|
deprecated and will be removed in Django 1.9.
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import warnings
|
import warnings
|
||||||
|
|
||||||
from django.test import SimpleTestCase
|
from django.test import SimpleTestCase, RequestFactory
|
||||||
from django.utils import six
|
from django.utils import six
|
||||||
|
from django.utils.datastructures import MergeDict
|
||||||
from django.utils.deprecation import RenameMethodsBase
|
from django.utils.deprecation import RenameMethodsBase
|
||||||
|
|
||||||
|
|
||||||
|
@ -156,3 +157,22 @@ class RenameMethodsTests(SimpleTestCase):
|
||||||
'`DeprecatedMixin.old` is deprecated, use `new` instead.',
|
'`DeprecatedMixin.old` is deprecated, use `new` instead.',
|
||||||
'`RenamedMixin.old` is deprecated, use `new` instead.',
|
'`RenamedMixin.old` is deprecated, use `new` instead.',
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
||||||
|
class DeprecatingRequestMergeDictTest(SimpleTestCase):
|
||||||
|
def test_deprecated_request(self):
|
||||||
|
"""
|
||||||
|
Ensure the correct warning is raised when WSGIRequest.REQUEST is
|
||||||
|
accessed.
|
||||||
|
"""
|
||||||
|
with warnings.catch_warnings(record=True) as recorded:
|
||||||
|
warnings.simplefilter('always')
|
||||||
|
request = RequestFactory().get('/')
|
||||||
|
_ = request.REQUEST
|
||||||
|
|
||||||
|
msgs = [str(warning.message) for warning in recorded]
|
||||||
|
self.assertEqual(msgs, [
|
||||||
|
'`request.REQUEST` is deprecated, use `request.GET` or '
|
||||||
|
'`request.POST` instead.',
|
||||||
|
'`MergeDict` is deprecated, use `dict.update()` instead.',
|
||||||
|
])
|
||||||
|
|
|
@ -3,6 +3,7 @@ from __future__ import unicode_literals
|
||||||
|
|
||||||
import copy
|
import copy
|
||||||
import datetime
|
import datetime
|
||||||
|
import warnings
|
||||||
|
|
||||||
from django.core.files.uploadedfile import SimpleUploadedFile
|
from django.core.files.uploadedfile import SimpleUploadedFile
|
||||||
from django.core.validators import RegexValidator
|
from django.core.validators import RegexValidator
|
||||||
|
@ -560,9 +561,12 @@ class FormsTestCase(TestCase):
|
||||||
f = SongForm(data)
|
f = SongForm(data)
|
||||||
self.assertEqual(f.errors, {})
|
self.assertEqual(f.errors, {})
|
||||||
|
|
||||||
data = MergeDict(MultiValueDict(dict(name=['Yesterday'], composers=['J', 'P'])))
|
# MergeDict is deprecated, but is supported until removed.
|
||||||
f = SongForm(data)
|
with warnings.catch_warnings(record=True):
|
||||||
self.assertEqual(f.errors, {})
|
warnings.simplefilter("always")
|
||||||
|
data = MergeDict(MultiValueDict(dict(name=['Yesterday'], composers=['J', 'P'])))
|
||||||
|
f = SongForm(data)
|
||||||
|
self.assertEqual(f.errors, {})
|
||||||
|
|
||||||
def test_multiple_hidden(self):
|
def test_multiple_hidden(self):
|
||||||
class SongForm(Form):
|
class SongForm(Form):
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import json
|
import json
|
||||||
|
import warnings
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.contrib.auth.decorators import login_required
|
from django.contrib.auth.decorators import login_required
|
||||||
|
@ -32,13 +33,20 @@ get_view = login_required(get_view)
|
||||||
|
|
||||||
def request_data(request, template='base.html', data='sausage'):
|
def request_data(request, template='base.html', data='sausage'):
|
||||||
"A simple view that returns the request data in the context"
|
"A simple view that returns the request data in the context"
|
||||||
|
|
||||||
|
# request.REQUEST is deprecated, but needs testing until removed.
|
||||||
|
with warnings.catch_warnings(record=True) as w:
|
||||||
|
warnings.simplefilter("always")
|
||||||
|
request_foo = request.REQUEST.get('foo')
|
||||||
|
request_bar = request.REQUEST.get('bar')
|
||||||
|
|
||||||
return render_to_response(template, {
|
return render_to_response(template, {
|
||||||
'get-foo':request.GET.get('foo',None),
|
'get-foo': request.GET.get('foo'),
|
||||||
'get-bar':request.GET.get('bar',None),
|
'get-bar': request.GET.get('bar'),
|
||||||
'post-foo':request.POST.get('foo',None),
|
'post-foo': request.POST.get('foo'),
|
||||||
'post-bar':request.POST.get('bar',None),
|
'post-bar': request.POST.get('bar'),
|
||||||
'request-foo':request.REQUEST.get('foo',None),
|
'request-foo': request_foo,
|
||||||
'request-bar':request.REQUEST.get('bar',None),
|
'request-bar': request_bar,
|
||||||
'data': data,
|
'data': data,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -136,7 +136,7 @@ class SortedDictTests(IgnorePendingDeprecationWarningsMixin, SimpleTestCase):
|
||||||
self.assertEqual(list(reversed(self.d2)), [7, 0, 9, 1])
|
self.assertEqual(list(reversed(self.d2)), [7, 0, 9, 1])
|
||||||
|
|
||||||
|
|
||||||
class MergeDictTests(SimpleTestCase):
|
class MergeDictTests(IgnorePendingDeprecationWarningsMixin, SimpleTestCase):
|
||||||
|
|
||||||
def test_simple_mergedict(self):
|
def test_simple_mergedict(self):
|
||||||
d1 = {'chris':'cool', 'camri':'cute', 'cotton':'adorable',
|
d1 = {'chris':'cool', 'camri':'cute', 'cotton':'adorable',
|
||||||
|
|
Loading…
Reference in New Issue