Skip to content

Commit c674687

Browse files
author
Carlton Gibson
authored
Remove Django 1.8 & 1.9 compatibility code (encode#5481)
* Identify code that needs to be pulled out of/removed from compat.py * Extract modern code from get_names_and_managers in compat.py and remove compat code * Extract modern code from is_authenticated() in compat.py and remove. * Extract modern code from is_anonymous() in compat.py and remove * Extract modern code from get_related_model() from compat.py and remove * Extract modern code from value_from_object() in compat.py and remove * Update postgres compat JSONField now always available. * Remove DecimalValidator compat * Remove get_remote_field compat * Remove template_render compat Plus isort. * Remove set_many compat * Remove include compat
1 parent 2edeb74 commit c674687

29 files changed

+95
-220
lines changed

rest_framework/authtoken/management/commands/drf_create_token.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from django.contrib.auth import get_user_model
22
from django.core.management.base import BaseCommand, CommandError
3-
from rest_framework.authtoken.models import Token
43

4+
from rest_framework.authtoken.models import Token
55

66
UserModel = get_user_model()
77

rest_framework/compat.py

+2-106
Original file line numberDiff line numberDiff line change
@@ -78,36 +78,6 @@ def distinct(queryset, base):
7878
return queryset.distinct()
7979

8080

81-
# Obtaining manager instances and names from model options differs after 1.10.
82-
def get_names_and_managers(options):
83-
if django.VERSION >= (1, 10):
84-
# Django 1.10 onwards provides a `.managers` property on the Options.
85-
return [
86-
(manager.name, manager)
87-
for manager
88-
in options.managers
89-
]
90-
# For Django 1.8 and 1.9, use the three-tuple information provided
91-
# by .concrete_managers and .abstract_managers
92-
return [
93-
(manager_info[1], manager_info[2])
94-
for manager_info
95-
in (options.concrete_managers + options.abstract_managers)
96-
]
97-
98-
99-
# field.rel is deprecated from 1.9 onwards
100-
def get_remote_field(field, **kwargs):
101-
if 'default' in kwargs:
102-
if django.VERSION < (1, 9):
103-
return getattr(field, 'rel', kwargs['default'])
104-
return getattr(field, 'remote_field', kwargs['default'])
105-
106-
if django.VERSION < (1, 9):
107-
return field.rel
108-
return field.remote_field
109-
110-
11181
def _resolve_model(obj):
11282
"""
11383
Resolve supplied `obj` to a Django model class.
@@ -132,44 +102,13 @@ def _resolve_model(obj):
132102
raise ValueError("{0} is not a Django model".format(obj))
133103

134104

135-
def is_authenticated(user):
136-
if django.VERSION < (1, 10):
137-
return user.is_authenticated()
138-
return user.is_authenticated
139-
140-
141-
def is_anonymous(user):
142-
if django.VERSION < (1, 10):
143-
return user.is_anonymous()
144-
return user.is_anonymous
145-
146-
147-
def get_related_model(field):
148-
if django.VERSION < (1, 9):
149-
return _resolve_model(field.rel.to)
150-
return field.remote_field.model
151-
152-
153-
def value_from_object(field, obj):
154-
if django.VERSION < (1, 9):
155-
return field._get_val_from_obj(obj)
156-
return field.value_from_object(obj)
157-
158-
159-
# contrib.postgres only supported from 1.8 onwards.
105+
# django.contrib.postgres requires psycopg2
160106
try:
161107
from django.contrib.postgres import fields as postgres_fields
162108
except ImportError:
163109
postgres_fields = None
164110

165111

166-
# JSONField is only supported from 1.9 onwards
167-
try:
168-
from django.contrib.postgres.fields import JSONField
169-
except ImportError:
170-
JSONField = None
171-
172-
173112
# coreapi is optional (Note that uritemplate is a dependency of coreapi)
174113
try:
175114
import coreapi
@@ -325,17 +264,12 @@ def md_filter_add_syntax_highlight(md):
325264
LONG_SEPARATORS = (b', ', b': ')
326265
INDENT_SEPARATORS = (b',', b': ')
327266

328-
try:
329-
# DecimalValidator is unavailable in Django < 1.9
330-
from django.core.validators import DecimalValidator
331-
except ImportError:
332-
DecimalValidator = None
333267

334268
class CustomValidatorMessage(object):
335269
"""
336270
We need to avoid evaluation of `lazy` translated `message` in `django.core.validators.BaseValidator.__init__`.
337271
https://github.com/django/django/blob/75ed5900321d170debef4ac452b8b3cf8a1c2384/django/core/validators.py#L297
338-
272+
339273
Ref: https://github.com/encode/django-rest-framework/pull/5452
340274
"""
341275
def __init__(self, *args, **kwargs):
@@ -371,44 +305,6 @@ def set_rollback():
371305
pass
372306

373307

374-
def template_render(template, context=None, request=None):
375-
"""
376-
Passing Context or RequestContext to Template.render is deprecated in 1.9+,
377-
see https://github.com/django/django/pull/3883 and
378-
https://github.com/django/django/blob/1.9/django/template/backends/django.py#L82-L84
379-
380-
:param template: Template instance
381-
:param context: dict
382-
:param request: Request instance
383-
:return: rendered template as SafeText instance
384-
"""
385-
if isinstance(template, Template):
386-
if request:
387-
context = RequestContext(request, context)
388-
else:
389-
context = Context(context)
390-
return template.render(context)
391-
# backends template, e.g. django.template.backends.django.Template
392-
else:
393-
return template.render(context, request=request)
394-
395-
396-
def set_many(instance, field, value):
397-
if django.VERSION < (1, 10):
398-
setattr(instance, field, value)
399-
else:
400-
field = getattr(instance, field)
401-
field.set(value)
402-
403-
404-
def include(module, namespace=None, app_name=None):
405-
from django.conf.urls import include
406-
if django.VERSION < (1,9):
407-
return include(module, namespace, app_name)
408-
else:
409-
return include((module, app_name), namespace)
410-
411-
412308
def authenticate(request=None, **credentials):
413309
from django.contrib.auth import authenticate
414310
if django.VERSION < (1, 11):

rest_framework/fields.py

+3-4
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,7 @@
3232
from rest_framework import ISO_8601
3333
from rest_framework.compat import (
3434
InvalidTimeError, MaxLengthValidator, MaxValueValidator,
35-
MinLengthValidator, MinValueValidator, get_remote_field, unicode_repr,
36-
unicode_to_repr, value_from_object
35+
MinLengthValidator, MinValueValidator, unicode_repr, unicode_to_repr
3736
)
3837
from rest_framework.exceptions import ErrorDetail, ValidationError
3938
from rest_framework.settings import api_settings
@@ -1829,7 +1828,7 @@ def __init__(self, model_field, **kwargs):
18291828
MaxLengthValidator(self.max_length, message=message))
18301829

18311830
def to_internal_value(self, data):
1832-
rel = get_remote_field(self.model_field, default=None)
1831+
rel = self.model_field.remote_field
18331832
if rel is not None:
18341833
return rel.model._meta.get_field(rel.field_name).to_python(data)
18351834
return self.model_field.to_python(data)
@@ -1840,7 +1839,7 @@ def get_attribute(self, obj):
18401839
return obj
18411840

18421841
def to_representation(self, obj):
1843-
value = value_from_object(self.model_field, obj)
1842+
value = self.model_field.value_from_object(obj)
18441843
if is_protected_type(value):
18451844
return value
18461845
return self.model_field.value_to_string(obj)

rest_framework/filters.py

+3-5
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,7 @@
1616
from django.utils.encoding import force_text
1717
from django.utils.translation import ugettext_lazy as _
1818

19-
from rest_framework.compat import (
20-
coreapi, coreschema, distinct, guardian, template_render
21-
)
19+
from rest_framework.compat import coreapi, coreschema, distinct, guardian
2220
from rest_framework.settings import api_settings
2321

2422

@@ -129,7 +127,7 @@ def to_html(self, request, queryset, view):
129127
'term': term
130128
}
131129
template = loader.get_template(self.template)
132-
return template_render(template, context)
130+
return template.render(context)
133131

134132
def get_schema_fields(self, view):
135133
assert coreapi is not None, 'coreapi must be installed to use `get_schema_fields()`'
@@ -260,7 +258,7 @@ def get_template_context(self, request, queryset, view):
260258
def to_html(self, request, queryset, view):
261259
template = loader.get_template(self.template)
262260
context = self.get_template_context(request, queryset, view)
263-
return template_render(template, context)
261+
return template.render(context)
264262

265263
def get_schema_fields(self, view):
266264
assert coreapi is not None, 'coreapi must be installed to use `get_schema_fields()`'

rest_framework/pagination.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
from django.utils.six.moves.urllib import parse as urlparse
1717
from django.utils.translation import ugettext_lazy as _
1818

19-
from rest_framework.compat import coreapi, coreschema, template_render
19+
from rest_framework.compat import coreapi, coreschema
2020
from rest_framework.exceptions import NotFound
2121
from rest_framework.response import Response
2222
from rest_framework.settings import api_settings
@@ -285,7 +285,7 @@ def page_number_to_url(page_number):
285285
def to_html(self):
286286
template = loader.get_template(self.template)
287287
context = self.get_html_context()
288-
return template_render(template, context)
288+
return template.render(context)
289289

290290
def get_schema_fields(self, view):
291291
assert coreapi is not None, 'coreapi must be installed to use `get_schema_fields()`'
@@ -442,7 +442,7 @@ def page_number_to_url(page_number):
442442
def to_html(self):
443443
template = loader.get_template(self.template)
444444
context = self.get_html_context()
445-
return template_render(template, context)
445+
return template.render(context)
446446

447447
def get_schema_fields(self, view):
448448
assert coreapi is not None, 'coreapi must be installed to use `get_schema_fields()`'
@@ -793,7 +793,7 @@ def get_html_context(self):
793793
def to_html(self):
794794
template = loader.get_template(self.template)
795795
context = self.get_html_context()
796-
return template_render(template, context)
796+
return template.render(context)
797797

798798
def get_schema_fields(self, view):
799799
assert coreapi is not None, 'coreapi must be installed to use `get_schema_fields()`'

rest_framework/permissions.py

+3-4
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
from django.http import Http404
77

88
from rest_framework import exceptions
9-
from rest_framework.compat import is_authenticated
109

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

@@ -47,7 +46,7 @@ class IsAuthenticated(BasePermission):
4746
"""
4847

4948
def has_permission(self, request, view):
50-
return request.user and is_authenticated(request.user)
49+
return request.user and request.user.is_authenticated
5150

5251

5352
class IsAdminUser(BasePermission):
@@ -68,7 +67,7 @@ def has_permission(self, request, view):
6867
return (
6968
request.method in SAFE_METHODS or
7069
request.user and
71-
is_authenticated(request.user)
70+
request.user.is_authenticated
7271
)
7372

7473

@@ -136,7 +135,7 @@ def has_permission(self, request, view):
136135
return True
137136

138137
if not request.user or (
139-
not is_authenticated(request.user) and self.authenticated_users_only):
138+
not request.user.is_authenticated and self.authenticated_users_only):
140139
return False
141140

142141
queryset = self._queryset(view)

rest_framework/renderers.py

+14-13
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,15 @@
1616
from django.core.exceptions import ImproperlyConfigured
1717
from django.core.paginator import Page
1818
from django.http.multipartparser import parse_header
19-
from django.template import Template, loader
19+
from django.template import engines, loader
2020
from django.test.client import encode_multipart
2121
from django.utils import six
2222
from django.utils.html import mark_safe
2323

2424
from rest_framework import VERSION, exceptions, serializers, status
2525
from rest_framework.compat import (
2626
INDENT_SEPARATORS, LONG_SEPARATORS, SHORT_SEPARATORS, coreapi,
27-
pygments_css, template_render
27+
pygments_css
2828
)
2929
from rest_framework.exceptions import ParseError
3030
from rest_framework.request import is_form_media_type, override_method
@@ -173,7 +173,7 @@ def render(self, data, accepted_media_type=None, renderer_context=None):
173173
context = self.resolve_context(data, request, response)
174174
else:
175175
context = self.get_template_context(data, renderer_context)
176-
return template_render(template, context, request=request)
176+
return template.render(context, request=request)
177177

178178
def resolve_template(self, template_names):
179179
return loader.select_template(template_names)
@@ -206,8 +206,9 @@ def get_exception_template(self, response):
206206
return self.resolve_template(template_names)
207207
except Exception:
208208
# Fall back to using eg '404 Not Found'
209-
return Template('%d %s' % (response.status_code,
210-
response.status_text.title()))
209+
body = '%d %s' % (response.status_code, response.status_text.title())
210+
template = engines['django'].from_string(body)
211+
return template
211212

212213

213214
# Note, subclass TemplateHTMLRenderer simply for the exception behavior
@@ -239,7 +240,7 @@ def render(self, data, accepted_media_type=None, renderer_context=None):
239240
context = self.resolve_context(data, request, response)
240241
else:
241242
context = self.get_template_context(data, renderer_context)
242-
return template_render(template, context, request=request)
243+
return template.render(context, request=request)
243244

244245
return data
245246

@@ -347,7 +348,7 @@ def render_field(self, field, parent_style):
347348

348349
template = loader.get_template(template_name)
349350
context = {'field': field, 'style': style}
350-
return template_render(template, context)
351+
return template.render(context)
351352

352353
def render(self, data, accepted_media_type=None, renderer_context=None):
353354
"""
@@ -368,7 +369,7 @@ def render(self, data, accepted_media_type=None, renderer_context=None):
368369
'form': form,
369370
'style': style
370371
}
371-
return template_render(template, context)
372+
return template.render(context)
372373

373374

374375
class BrowsableAPIRenderer(BaseRenderer):
@@ -625,7 +626,7 @@ def get_filter_form(self, data, view, request):
625626

626627
template = loader.get_template(self.filter_template)
627628
context = {'elements': elements}
628-
return template_render(template, context)
629+
return template.render(context)
629630

630631
def get_context(self, data, accepted_media_type, renderer_context):
631632
"""
@@ -705,7 +706,7 @@ def render(self, data, accepted_media_type=None, renderer_context=None):
705706

706707
template = loader.get_template(self.template)
707708
context = self.get_context(data, accepted_media_type, renderer_context)
708-
ret = template_render(template, context, request=renderer_context['request'])
709+
ret = template.render(context, request=renderer_context['request'])
709710

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

742743
template = loader.get_template(self.template)
743744
context = self.get_context(data, accepted_media_type, renderer_context)
744-
ret = template_render(template, context, request=renderer_context['request'])
745+
ret = template.render(context, request=renderer_context['request'])
745746

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

824825

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

840841

841842
class MultiPartRenderer(BaseRenderer):

0 commit comments

Comments
 (0)