Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove Django 1.8 & 1.9 compatibility code #5481

Merged
merged 12 commits into from
Oct 5, 2017
Merged
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from django.contrib.auth import get_user_model
from django.core.management.base import BaseCommand, CommandError
from rest_framework.authtoken.models import Token

from rest_framework.authtoken.models import Token

UserModel = get_user_model()

Expand Down
108 changes: 2 additions & 106 deletions rest_framework/compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,36 +78,6 @@ def distinct(queryset, base):
return queryset.distinct()


# Obtaining manager instances and names from model options differs after 1.10.
def get_names_and_managers(options):
if django.VERSION >= (1, 10):
# Django 1.10 onwards provides a `.managers` property on the Options.
return [
(manager.name, manager)
for manager
in options.managers
]
# For Django 1.8 and 1.9, use the three-tuple information provided
# by .concrete_managers and .abstract_managers
return [
(manager_info[1], manager_info[2])
for manager_info
in (options.concrete_managers + options.abstract_managers)
]


# field.rel is deprecated from 1.9 onwards
def get_remote_field(field, **kwargs):
if 'default' in kwargs:
if django.VERSION < (1, 9):
return getattr(field, 'rel', kwargs['default'])
return getattr(field, 'remote_field', kwargs['default'])

if django.VERSION < (1, 9):
return field.rel
return field.remote_field


def _resolve_model(obj):
"""
Resolve supplied `obj` to a Django model class.
Expand All @@ -132,44 +102,13 @@ def _resolve_model(obj):
raise ValueError("{0} is not a Django model".format(obj))


def is_authenticated(user):
if django.VERSION < (1, 10):
return user.is_authenticated()
return user.is_authenticated


def is_anonymous(user):
if django.VERSION < (1, 10):
return user.is_anonymous()
return user.is_anonymous


def get_related_model(field):
if django.VERSION < (1, 9):
return _resolve_model(field.rel.to)
return field.remote_field.model


def value_from_object(field, obj):
if django.VERSION < (1, 9):
return field._get_val_from_obj(obj)
return field.value_from_object(obj)


# contrib.postgres only supported from 1.8 onwards.
# django.contrib.postgres requires psycopg2
try:
from django.contrib.postgres import fields as postgres_fields
except ImportError:
postgres_fields = None


# JSONField is only supported from 1.9 onwards
try:
from django.contrib.postgres.fields import JSONField
except ImportError:
JSONField = None


# coreapi is optional (Note that uritemplate is a dependency of coreapi)
try:
import coreapi
Expand Down Expand Up @@ -325,17 +264,12 @@ def md_filter_add_syntax_highlight(md):
LONG_SEPARATORS = (b', ', b': ')
INDENT_SEPARATORS = (b',', b': ')

try:
# DecimalValidator is unavailable in Django < 1.9
from django.core.validators import DecimalValidator
except ImportError:
DecimalValidator = None

class CustomValidatorMessage(object):
"""
We need to avoid evaluation of `lazy` translated `message` in `django.core.validators.BaseValidator.__init__`.
https://github.com/django/django/blob/75ed5900321d170debef4ac452b8b3cf8a1c2384/django/core/validators.py#L297

Ref: https://github.com/encode/django-rest-framework/pull/5452
"""
def __init__(self, *args, **kwargs):
Expand Down Expand Up @@ -371,44 +305,6 @@ def set_rollback():
pass


def template_render(template, context=None, request=None):
"""
Passing Context or RequestContext to Template.render is deprecated in 1.9+,
see https://github.com/django/django/pull/3883 and
https://github.com/django/django/blob/1.9/django/template/backends/django.py#L82-L84

:param template: Template instance
:param context: dict
:param request: Request instance
:return: rendered template as SafeText instance
"""
if isinstance(template, Template):
if request:
context = RequestContext(request, context)
else:
context = Context(context)
return template.render(context)
# backends template, e.g. django.template.backends.django.Template
else:
return template.render(context, request=request)


def set_many(instance, field, value):
if django.VERSION < (1, 10):
setattr(instance, field, value)
else:
field = getattr(instance, field)
field.set(value)


def include(module, namespace=None, app_name=None):
from django.conf.urls import include
if django.VERSION < (1,9):
return include(module, namespace, app_name)
else:
return include((module, app_name), namespace)


def authenticate(request=None, **credentials):
from django.contrib.auth import authenticate
if django.VERSION < (1, 11):
Expand Down
7 changes: 3 additions & 4 deletions rest_framework/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,7 @@
from rest_framework import ISO_8601
from rest_framework.compat import (
InvalidTimeError, MaxLengthValidator, MaxValueValidator,
MinLengthValidator, MinValueValidator, get_remote_field, unicode_repr,
unicode_to_repr, value_from_object
MinLengthValidator, MinValueValidator, unicode_repr, unicode_to_repr
)
from rest_framework.exceptions import ErrorDetail, ValidationError
from rest_framework.settings import api_settings
Expand Down Expand Up @@ -1829,7 +1828,7 @@ def __init__(self, model_field, **kwargs):
MaxLengthValidator(self.max_length, message=message))

def to_internal_value(self, data):
rel = get_remote_field(self.model_field, default=None)
rel = self.model_field.remote_field
if rel is not None:
return rel.model._meta.get_field(rel.field_name).to_python(data)
return self.model_field.to_python(data)
Expand All @@ -1840,7 +1839,7 @@ def get_attribute(self, obj):
return obj

def to_representation(self, obj):
value = value_from_object(self.model_field, obj)
value = self.model_field.value_from_object(obj)
if is_protected_type(value):
return value
return self.model_field.value_to_string(obj)
8 changes: 3 additions & 5 deletions rest_framework/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,7 @@
from django.utils.encoding import force_text
from django.utils.translation import ugettext_lazy as _

from rest_framework.compat import (
coreapi, coreschema, distinct, guardian, template_render
)
from rest_framework.compat import coreapi, coreschema, distinct, guardian
from rest_framework.settings import api_settings


Expand Down Expand Up @@ -129,7 +127,7 @@ def to_html(self, request, queryset, view):
'term': term
}
template = loader.get_template(self.template)
return template_render(template, context)
return template.render(context)

def get_schema_fields(self, view):
assert coreapi is not None, 'coreapi must be installed to use `get_schema_fields()`'
Expand Down Expand Up @@ -260,7 +258,7 @@ def get_template_context(self, request, queryset, view):
def to_html(self, request, queryset, view):
template = loader.get_template(self.template)
context = self.get_template_context(request, queryset, view)
return template_render(template, context)
return template.render(context)

def get_schema_fields(self, view):
assert coreapi is not None, 'coreapi must be installed to use `get_schema_fields()`'
Expand Down
8 changes: 4 additions & 4 deletions rest_framework/pagination.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
from django.utils.six.moves.urllib import parse as urlparse
from django.utils.translation import ugettext_lazy as _

from rest_framework.compat import coreapi, coreschema, template_render
from rest_framework.compat import coreapi, coreschema
from rest_framework.exceptions import NotFound
from rest_framework.response import Response
from rest_framework.settings import api_settings
Expand Down Expand Up @@ -285,7 +285,7 @@ def page_number_to_url(page_number):
def to_html(self):
template = loader.get_template(self.template)
context = self.get_html_context()
return template_render(template, context)
return template.render(context)

def get_schema_fields(self, view):
assert coreapi is not None, 'coreapi must be installed to use `get_schema_fields()`'
Expand Down Expand Up @@ -442,7 +442,7 @@ def page_number_to_url(page_number):
def to_html(self):
template = loader.get_template(self.template)
context = self.get_html_context()
return template_render(template, context)
return template.render(context)

def get_schema_fields(self, view):
assert coreapi is not None, 'coreapi must be installed to use `get_schema_fields()`'
Expand Down Expand Up @@ -793,7 +793,7 @@ def get_html_context(self):
def to_html(self):
template = loader.get_template(self.template)
context = self.get_html_context()
return template_render(template, context)
return template.render(context)

def get_schema_fields(self, view):
assert coreapi is not None, 'coreapi must be installed to use `get_schema_fields()`'
Expand Down
7 changes: 3 additions & 4 deletions rest_framework/permissions.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
from django.http import Http404

from rest_framework import exceptions
from rest_framework.compat import is_authenticated

SAFE_METHODS = ('GET', 'HEAD', 'OPTIONS')

Expand Down Expand Up @@ -47,7 +46,7 @@ class IsAuthenticated(BasePermission):
"""

def has_permission(self, request, view):
return request.user and is_authenticated(request.user)
return request.user and request.user.is_authenticated


class IsAdminUser(BasePermission):
Expand All @@ -68,7 +67,7 @@ def has_permission(self, request, view):
return (
request.method in SAFE_METHODS or
request.user and
is_authenticated(request.user)
request.user.is_authenticated
)


Expand Down Expand Up @@ -136,7 +135,7 @@ def has_permission(self, request, view):
return True

if not request.user or (
not is_authenticated(request.user) and self.authenticated_users_only):
not request.user.is_authenticated and self.authenticated_users_only):
return False

queryset = self._queryset(view)
Expand Down
27 changes: 14 additions & 13 deletions rest_framework/renderers.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,15 @@
from django.core.exceptions import ImproperlyConfigured
from django.core.paginator import Page
from django.http.multipartparser import parse_header
from django.template import Template, loader
from django.template import engines, loader
from django.test.client import encode_multipart
from django.utils import six
from django.utils.html import mark_safe

from rest_framework import VERSION, exceptions, serializers, status
from rest_framework.compat import (
INDENT_SEPARATORS, LONG_SEPARATORS, SHORT_SEPARATORS, coreapi,
pygments_css, template_render
pygments_css
)
from rest_framework.exceptions import ParseError
from rest_framework.request import is_form_media_type, override_method
Expand Down Expand Up @@ -173,7 +173,7 @@ def render(self, data, accepted_media_type=None, renderer_context=None):
context = self.resolve_context(data, request, response)
else:
context = self.get_template_context(data, renderer_context)
return template_render(template, context, request=request)
return template.render(context, request=request)

def resolve_template(self, template_names):
return loader.select_template(template_names)
Expand Down Expand Up @@ -206,8 +206,9 @@ def get_exception_template(self, response):
return self.resolve_template(template_names)
except Exception:
# Fall back to using eg '404 Not Found'
return Template('%d %s' % (response.status_code,
response.status_text.title()))
body = '%d %s' % (response.status_code, response.status_text.title())
template = engines['django'].from_string(body)
return template


# Note, subclass TemplateHTMLRenderer simply for the exception behavior
Expand Down Expand Up @@ -239,7 +240,7 @@ def render(self, data, accepted_media_type=None, renderer_context=None):
context = self.resolve_context(data, request, response)
else:
context = self.get_template_context(data, renderer_context)
return template_render(template, context, request=request)
return template.render(context, request=request)

return data

Expand Down Expand Up @@ -347,7 +348,7 @@ def render_field(self, field, parent_style):

template = loader.get_template(template_name)
context = {'field': field, 'style': style}
return template_render(template, context)
return template.render(context)

def render(self, data, accepted_media_type=None, renderer_context=None):
"""
Expand All @@ -368,7 +369,7 @@ def render(self, data, accepted_media_type=None, renderer_context=None):
'form': form,
'style': style
}
return template_render(template, context)
return template.render(context)


class BrowsableAPIRenderer(BaseRenderer):
Expand Down Expand Up @@ -625,7 +626,7 @@ def get_filter_form(self, data, view, request):

template = loader.get_template(self.filter_template)
context = {'elements': elements}
return template_render(template, context)
return template.render(context)

def get_context(self, data, accepted_media_type, renderer_context):
"""
Expand Down Expand Up @@ -705,7 +706,7 @@ def render(self, data, accepted_media_type=None, renderer_context=None):

template = loader.get_template(self.template)
context = self.get_context(data, accepted_media_type, renderer_context)
ret = template_render(template, context, request=renderer_context['request'])
ret = template.render(context, request=renderer_context['request'])

# Munge DELETE Response code to allow us to return content
# (Do this *after* we've rendered the template so that we include
Expand Down Expand Up @@ -741,7 +742,7 @@ def render(self, data, accepted_media_type=None, renderer_context=None):

template = loader.get_template(self.template)
context = self.get_context(data, accepted_media_type, renderer_context)
ret = template_render(template, context, request=renderer_context['request'])
ret = template.render(context, request=renderer_context['request'])

# Creation and deletion should use redirects in the admin style.
if response.status_code == status.HTTP_201_CREATED and 'Location' in response:
Expand Down Expand Up @@ -819,7 +820,7 @@ def get_context(self, data, request):
def render(self, data, accepted_media_type=None, renderer_context=None):
template = loader.get_template(self.template)
context = self.get_context(data, renderer_context['request'])
return template_render(template, context, request=renderer_context['request'])
return template.render(context, request=renderer_context['request'])


class SchemaJSRenderer(BaseRenderer):
Expand All @@ -835,7 +836,7 @@ def render(self, data, accepted_media_type=None, renderer_context=None):
template = loader.get_template(self.template)
context = {'schema': mark_safe(schema)}
request = renderer_context['request']
return template_render(template, context, request=request)
return template.render(context, request=request)


class MultiPartRenderer(BaseRenderer):
Expand Down
Loading