Merge pull request #3230 from maryokhin/master

Fully drop Django 1.4 support
This commit is contained in:
Tom Christie 2015-08-07 09:57:28 +01:00
commit 77867e1eef
7 changed files with 29 additions and 57 deletions

View File

@ -5,13 +5,12 @@ from __future__ import unicode_literals
import base64 import base64
from django.contrib.auth import authenticate from django.contrib.auth import authenticate, get_user_model
from django.middleware.csrf import CsrfViewMiddleware from django.middleware.csrf import CsrfViewMiddleware
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from rest_framework import HTTP_HEADER_ENCODING, exceptions from rest_framework import HTTP_HEADER_ENCODING, exceptions
from rest_framework.authtoken.models import Token from rest_framework.authtoken.models import Token
from rest_framework.compat import get_user_model
def get_authorization_header(request): def get_authorization_header(request):
@ -89,9 +88,8 @@ class BasicAuthentication(BaseAuthentication):
""" """
Authenticate the userid and password against username and password. Authenticate the userid and password against username and password.
""" """
username_field = getattr(get_user_model(), 'USERNAME_FIELD', 'username')
credentials = { credentials = {
username_field: userid, get_user_model().USERNAME_FIELD: userid,
'password': password 'password': password
} }
user = authenticate(**credentials) user = authenticate(**credentials)

View File

@ -1,27 +1,22 @@
""" """
The `compat` module provides support for backwards compatibility with older The `compat` module provides support for backwards compatibility with older
versions of django/python, and compatibility wrappers around optional packages. versions of Django/Python, and compatibility wrappers around optional packages.
""" """
# flake8: noqa # flake8: noqa
from __future__ import unicode_literals from __future__ import unicode_literals
import inspect
import django import django
from django.conf import settings from django.conf import settings
from django.core.exceptions import ImproperlyConfigured
from django.db import connection, transaction from django.db import connection, transaction
from django.forms import FilePathField as DjangoFilePathField
from django.test.client import FakePayload
from django.utils import six from django.utils import six
from django.utils.encoding import force_text from django.views.generic import View
from django.utils.six.moves.urllib.parse import urlparse as _urlparse
try: try:
import importlib import importlib # Available in Python 3.1+
except ImportError: except ImportError:
from django.utils import importlib from django.utils import importlib # Will be removed in Django 1.9
def unicode_repr(instance): def unicode_repr(instance):
# Get the repr of an instance, but ensure it is a unicode string # Get the repr of an instance, but ensure it is a unicode string
@ -65,13 +60,6 @@ except ImportError:
from django.utils.datastructures import SortedDict as OrderedDict from django.utils.datastructures import SortedDict as OrderedDict
# HttpResponseBase only exists from 1.5 onwards
try:
from django.http.response import HttpResponseBase
except ImportError:
from django.http import HttpResponse as HttpResponseBase
# contrib.postgres only supported from 1.8 onwards. # contrib.postgres only supported from 1.8 onwards.
try: try:
from django.contrib.postgres import fields as postgres_fields from django.contrib.postgres import fields as postgres_fields
@ -79,16 +67,6 @@ except ImportError:
postgres_fields = None postgres_fields = None
# request only provides `resolver_match` from 1.5 onwards.
def get_resolver_match(request):
try:
return request.resolver_match
except AttributeError:
# Django < 1.5
from django.core.urlresolvers import resolve
return resolve(request.path_info)
# django-filter is optional # django-filter is optional
try: try:
import django_filters import django_filters
@ -125,25 +103,6 @@ def get_model_name(model_cls):
return model_cls._meta.module_name return model_cls._meta.module_name
# Support custom user models in Django 1.5+
try:
from django.contrib.auth import get_user_model
except ImportError:
from django.contrib.auth.models import User
get_user_model = lambda: User
# View._allowed_methods only present from 1.5 onwards
if django.VERSION >= (1, 5):
from django.views.generic import View
else:
from django.views.generic import View as DjangoView
class View(DjangoView):
def _allowed_methods(self):
return [m.upper() for m in self.http_method_names if hasattr(self, m)]
# MinValueValidator, MaxValueValidator et al. only accept `message` in 1.8+ # MinValueValidator, MaxValueValidator et al. only accept `message` in 1.8+
if django.VERSION >= (1, 8): if django.VERSION >= (1, 8):
from django.core.validators import MinValueValidator, MaxValueValidator from django.core.validators import MinValueValidator, MaxValueValidator
@ -154,21 +113,25 @@ else:
from django.core.validators import MinLengthValidator as DjangoMinLengthValidator from django.core.validators import MinLengthValidator as DjangoMinLengthValidator
from django.core.validators import MaxLengthValidator as DjangoMaxLengthValidator from django.core.validators import MaxLengthValidator as DjangoMaxLengthValidator
class MinValueValidator(DjangoMinValueValidator): class MinValueValidator(DjangoMinValueValidator):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
self.message = kwargs.pop('message', self.message) self.message = kwargs.pop('message', self.message)
super(MinValueValidator, self).__init__(*args, **kwargs) super(MinValueValidator, self).__init__(*args, **kwargs)
class MaxValueValidator(DjangoMaxValueValidator): class MaxValueValidator(DjangoMaxValueValidator):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
self.message = kwargs.pop('message', self.message) self.message = kwargs.pop('message', self.message)
super(MaxValueValidator, self).__init__(*args, **kwargs) super(MaxValueValidator, self).__init__(*args, **kwargs)
class MinLengthValidator(DjangoMinLengthValidator): class MinLengthValidator(DjangoMinLengthValidator):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
self.message = kwargs.pop('message', self.message) self.message = kwargs.pop('message', self.message)
super(MinLengthValidator, self).__init__(*args, **kwargs) super(MinLengthValidator, self).__init__(*args, **kwargs)
class MaxLengthValidator(DjangoMaxLengthValidator): class MaxLengthValidator(DjangoMaxLengthValidator):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
self.message = kwargs.pop('message', self.message) self.message = kwargs.pop('message', self.message)
@ -181,6 +144,7 @@ if django.VERSION >= (1, 6):
else: else:
from django.core.validators import URLValidator as DjangoURLValidator from django.core.validators import URLValidator as DjangoURLValidator
class URLValidator(DjangoURLValidator): class URLValidator(DjangoURLValidator):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
self.message = kwargs.pop('message', self.message) self.message = kwargs.pop('message', self.message)
@ -194,6 +158,7 @@ else:
from django.core.validators import EmailValidator as DjangoEmailValidator from django.core.validators import EmailValidator as DjangoEmailValidator
from django.core.validators import email_re from django.core.validators import email_re
class EmailValidator(DjangoEmailValidator): class EmailValidator(DjangoEmailValidator):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super(EmailValidator, self).__init__(email_re, *args, **kwargs) super(EmailValidator, self).__init__(email_re, *args, **kwargs)
@ -208,6 +173,7 @@ if 'patch' not in View.http_method_names:
try: try:
import markdown import markdown
def apply_markdown(text): def apply_markdown(text):
""" """
Simple wrapper around :func:`markdown.markdown` to set the base level Simple wrapper around :func:`markdown.markdown` to set the base level
@ -233,7 +199,6 @@ else:
LONG_SEPARATORS = (b', ', b': ') LONG_SEPARATORS = (b', ', b': ')
INDENT_SEPARATORS = (b',', b': ') INDENT_SEPARATORS = (b',', b': ')
if django.VERSION >= (1, 8): if django.VERSION >= (1, 8):
from django.db.models import DurationField from django.db.models import DurationField
from django.utils.dateparse import parse_duration from django.utils.dateparse import parse_duration

View File

@ -23,7 +23,7 @@ from django.core.exceptions import ImproperlyConfigured
from django.core.urlresolvers import NoReverseMatch from django.core.urlresolvers import NoReverseMatch
from rest_framework import views from rest_framework import views
from rest_framework.compat import OrderedDict, get_resolver_match from rest_framework.compat import OrderedDict
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework.reverse import reverse from rest_framework.reverse import reverse
from rest_framework.urlpatterns import format_suffix_patterns from rest_framework.urlpatterns import format_suffix_patterns
@ -284,7 +284,7 @@ class DefaultRouter(SimpleRouter):
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
ret = OrderedDict() ret = OrderedDict()
namespace = get_resolver_match(request).namespace namespace = request.resolver_match.namespace
for key, url_name in api_root_dict.items(): for key, url_name in api_root_dict.items():
if namespace: if namespace:
url_name = namespace + ':' + url_name url_name = namespace + ':' + url_name

View File

@ -5,10 +5,11 @@ from __future__ import unicode_literals
import re import re
from django.utils.encoding import force_text
from django.utils.html import escape from django.utils.html import escape
from django.utils.safestring import mark_safe from django.utils.safestring import mark_safe
from rest_framework.compat import apply_markdown, force_text from rest_framework.compat import apply_markdown
def remove_trailing_string(content, trailing): def remove_trailing_string(content, trailing):

View File

@ -2,7 +2,9 @@ from __future__ import unicode_literals
import collections import collections
from rest_framework.compat import OrderedDict, force_text, unicode_to_repr from django.utils.encoding import force_text
from rest_framework.compat import OrderedDict, unicode_to_repr
class ReturnDict(OrderedDict): class ReturnDict(OrderedDict):
@ -11,6 +13,7 @@ class ReturnDict(OrderedDict):
Includes a backlink to the serializer instance for renderers Includes a backlink to the serializer instance for renderers
to use if they need richer field information. to use if they need richer field information.
""" """
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
self.serializer = kwargs.pop('serializer') self.serializer = kwargs.pop('serializer')
super(ReturnDict, self).__init__(*args, **kwargs) super(ReturnDict, self).__init__(*args, **kwargs)
@ -33,6 +36,7 @@ class ReturnList(list):
Includes a backlink to the serializer instance for renderers Includes a backlink to the serializer instance for renderers
to use if they need richer field information. to use if they need richer field information.
""" """
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
self.serializer = kwargs.pop('serializer') self.serializer = kwargs.pop('serializer')
super(ReturnList, self).__init__(*args, **kwargs) super(ReturnList, self).__init__(*args, **kwargs)
@ -52,6 +56,7 @@ class BoundField(object):
Returned when iterating over a serializer instance, Returned when iterating over a serializer instance,
providing an API similar to Django forms and form fields. providing an API similar to Django forms and form fields.
""" """
def __init__(self, field, value, errors, prefix=''): def __init__(self, field, value, errors, prefix=''):
self._field = field self._field = field
self._prefix = prefix self._prefix = prefix
@ -82,6 +87,7 @@ class NestedBoundField(BoundField):
in order to support nested bound fields. This class is the type of in order to support nested bound fields. This class is the type of
`BoundField` that is used for serializer fields. `BoundField` that is used for serializer fields.
""" """
def __iter__(self): def __iter__(self):
for field in self.fields.values(): for field in self.fields.values():
yield self[field.field_name] yield self[field.field_name]
@ -112,6 +118,7 @@ class BindingDict(collections.MutableMapping):
`field.bind()` so that the `field_name` and `parent` attributes `field.bind()` so that the `field_name` and `parent` attributes
can be set correctly. can be set correctly.
""" """
def __init__(self, serializer): def __init__(self, serializer):
self.serializer = serializer self.serializer = serializer
self.fields = OrderedDict() self.fields = OrderedDict()

View File

@ -6,13 +6,15 @@ from __future__ import unicode_literals
from django.core.exceptions import PermissionDenied from django.core.exceptions import PermissionDenied
from django.db import models from django.db import models
from django.http import Http404 from django.http import Http404
from django.http.response import HttpResponseBase
from django.utils import six from django.utils import six
from django.utils.encoding import smart_text from django.utils.encoding import smart_text
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django.views.decorators.csrf import csrf_exempt from django.views.decorators.csrf import csrf_exempt
from django.views.generic import View
from rest_framework import exceptions, status from rest_framework import exceptions, status
from rest_framework.compat import HttpResponseBase, View, set_rollback from rest_framework.compat import set_rollback
from rest_framework.request import Request from rest_framework.request import Request
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework.settings import api_settings from rest_framework.settings import api_settings

View File

@ -4,7 +4,6 @@ addopts=--tb=short
[tox] [tox]
envlist = envlist =
py27-{lint,docs}, py27-{lint,docs},
{py26,py27}-django14,
{py26,py27,py32,py33,py34}-django{15,16}, {py26,py27,py32,py33,py34}-django{15,16},
{py27,py32,py33,py34}-django{17,18,master} {py27,py32,py33,py34}-django{17,18,master}