Merge pull request #3421 from carltongibson/supported-versions-2

Drop Django 1.5
This commit is contained in:
Tom Christie 2015-09-22 12:48:11 +01:00
commit 5b2b675a21
10 changed files with 37 additions and 75 deletions

View File

@ -18,23 +18,16 @@ env:
- TOX_ENV=py32-django16 - TOX_ENV=py32-django16
- TOX_ENV=py27-django16 - TOX_ENV=py27-django16
- TOX_ENV=py26-django16 - TOX_ENV=py26-django16
- TOX_ENV=py34-django15
- TOX_ENV=py33-django15
- TOX_ENV=py32-django15
- TOX_ENV=py27-django15
- TOX_ENV=py26-django15
- TOX_ENV=py27-djangomaster - TOX_ENV=py27-djangomaster
- TOX_ENV=py32-djangomaster
- TOX_ENV=py33-djangomaster
- TOX_ENV=py34-djangomaster - TOX_ENV=py34-djangomaster
- TOX_ENV=py35-djangomaster
matrix: matrix:
fast_finish: true fast_finish: true
allow_failures: allow_failures:
- env: TOX_ENV=py27-djangomaster - env: TOX_ENV=py27-djangomaster
- env: TOX_ENV=py32-djangomaster
- env: TOX_ENV=py33-djangomaster
- env: TOX_ENV=py34-djangomaster - env: TOX_ENV=py34-djangomaster
- env: TOX_ENV=py35-djangomaster
install: install:
- pip install tox - pip install tox

View File

@ -37,7 +37,7 @@ There is a live example API for testing purposes, [available here][sandbox].
# Requirements # Requirements
* Python (2.6.5+, 2.7, 3.2, 3.3, 3.4) * Python (2.6.5+, 2.7, 3.2, 3.3, 3.4)
* Django (1.5.6+, 1.6.3+, 1.7, 1.8) * Django (1.6.3+, 1.7, 1.8)
# Installation # Installation

View File

@ -38,6 +38,14 @@ You can determine your currently installed version using `pip freeze`:
--- ---
## 3.3.x series
### 3.0.0
**Date**: NOT YET RELEASED
* Removed support for Django Version 1.5 ([#3421][gh3421])
## 3.2.x series ## 3.2.x series
### 3.2.3 ### 3.2.3
@ -514,5 +522,6 @@ For older release notes, [please see the version 2.x documentation][old-release-
[gh3321]: https://github.com/tomchristie/django-rest-framework/issues/3321 [gh3321]: https://github.com/tomchristie/django-rest-framework/issues/3321
<!-- 3.0.0 -->
[gh3421]: https://github.com/tomchristie/django-rest-framework/pulls/3421

View File

@ -106,17 +106,6 @@ try:
except ImportError: except ImportError:
django_filters = None django_filters = None
if django.VERSION >= (1, 6):
def clean_manytomany_helptext(text):
return text
else:
# Up to version 1.5 many to many fields automatically suffix
# the `help_text` attribute with hardcoded text.
def clean_manytomany_helptext(text):
if text.endswith(' Hold down "Control", or "Command" on a Mac, to select more than one.'):
text = text[:-69]
return text
# Django-guardian is optional. Import only if guardian is in INSTALLED_APPS # Django-guardian is optional. Import only if guardian is in INSTALLED_APPS
# Fixes (#1712). We keep the try/except for the test suite. # Fixes (#1712). We keep the try/except for the test suite.
guardian = None guardian = None
@ -127,14 +116,6 @@ except ImportError:
pass pass
def get_model_name(model_cls):
try:
return model_cls._meta.model_name
except AttributeError:
# < 1.6 used module_name instead of model_name
return model_cls._meta.module_name
# 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
@ -170,32 +151,6 @@ else:
super(MaxLengthValidator, self).__init__(*args, **kwargs) super(MaxLengthValidator, self).__init__(*args, **kwargs)
# URLValidator only accepts `message` in 1.6+
if django.VERSION >= (1, 6):
from django.core.validators import URLValidator
else:
from django.core.validators import URLValidator as DjangoURLValidator
class URLValidator(DjangoURLValidator):
def __init__(self, *args, **kwargs):
self.message = kwargs.pop('message', self.message)
super(URLValidator, self).__init__(*args, **kwargs)
# EmailValidator requires explicit regex prior to 1.6+
if django.VERSION >= (1, 6):
from django.core.validators import EmailValidator
else:
from django.core.validators import EmailValidator as DjangoEmailValidator
from django.core.validators import email_re
class EmailValidator(DjangoEmailValidator):
def __init__(self, *args, **kwargs):
super(EmailValidator, self).__init__(email_re, *args, **kwargs)
# PATCH method is not implemented by Django # PATCH method is not implemented by Django
if 'patch' not in View.http_method_names: if 'patch' not in View.http_method_names:
View.http_method_names = View.http_method_names + ['patch'] View.http_method_names = View.http_method_names + ['patch']

View File

@ -11,7 +11,9 @@ import uuid
from django.conf import settings from django.conf import settings
from django.core.exceptions import ValidationError as DjangoValidationError from django.core.exceptions import ValidationError as DjangoValidationError
from django.core.exceptions import ObjectDoesNotExist from django.core.exceptions import ObjectDoesNotExist
from django.core.validators import RegexValidator, ip_address_validators from django.core.validators import (
EmailValidator, RegexValidator, URLValidator, ip_address_validators
)
from django.forms import FilePathField as DjangoFilePathField from django.forms import FilePathField as DjangoFilePathField
from django.forms import ImageField as DjangoImageField from django.forms import ImageField as DjangoImageField
from django.utils import six, timezone from django.utils import six, timezone
@ -23,9 +25,9 @@ from django.utils.translation import ugettext_lazy as _
from rest_framework import ISO_8601 from rest_framework import ISO_8601
from rest_framework.compat import ( from rest_framework.compat import (
EmailValidator, MaxLengthValidator, MaxValueValidator, MinLengthValidator, MaxLengthValidator, MaxValueValidator, MinLengthValidator,
MinValueValidator, OrderedDict, URLValidator, duration_string, MinValueValidator, OrderedDict, duration_string, parse_duration,
parse_duration, unicode_repr, unicode_to_repr unicode_repr, unicode_to_repr
) )
from rest_framework.exceptions import ValidationError from rest_framework.exceptions import ValidationError
from rest_framework.settings import api_settings from rest_framework.settings import api_settings

View File

@ -11,9 +11,7 @@ from django.core.exceptions import ImproperlyConfigured
from django.db import models from django.db import models
from django.utils import six from django.utils import six
from rest_framework.compat import ( from rest_framework.compat import distinct, django_filters, guardian
distinct, django_filters, get_model_name, guardian
)
from rest_framework.settings import api_settings from rest_framework.settings import api_settings
FilterSet = django_filters and django_filters.FilterSet or None FilterSet = django_filters and django_filters.FilterSet or None
@ -202,7 +200,7 @@ class DjangoObjectPermissionsFilter(BaseFilterBackend):
model_cls = queryset.model model_cls = queryset.model
kwargs = { kwargs = {
'app_label': model_cls._meta.app_label, 'app_label': model_cls._meta.app_label,
'model_name': get_model_name(model_cls) 'model_name': model_cls._meta.model_name
} }
permission = self.perm_format % kwargs permission = self.perm_format % kwargs
if guardian.VERSION >= (1, 3): if guardian.VERSION >= (1, 3):

View File

@ -5,8 +5,6 @@ from __future__ import unicode_literals
from django.http import Http404 from django.http import Http404
from rest_framework.compat import get_model_name
SAFE_METHODS = ('GET', 'HEAD', 'OPTIONS') SAFE_METHODS = ('GET', 'HEAD', 'OPTIONS')
@ -104,7 +102,7 @@ class DjangoModelPermissions(BasePermission):
""" """
kwargs = { kwargs = {
'app_label': model_cls._meta.app_label, 'app_label': model_cls._meta.app_label,
'model_name': get_model_name(model_cls) 'model_name': model_cls._meta.model_name
} }
return [perm % kwargs for perm in self.perms_map[method]] return [perm % kwargs for perm in self.perms_map[method]]
@ -166,7 +164,7 @@ class DjangoObjectPermissions(DjangoModelPermissions):
def get_required_object_permissions(self, method, model_cls): def get_required_object_permissions(self, method, model_cls):
kwargs = { kwargs = {
'app_label': model_cls._meta.app_label, 'app_label': model_cls._meta.app_label,
'model_name': get_model_name(model_cls) 'model_name': model_cls._meta.model_name
} }
return [perm % kwargs for perm in self.perms_map[method]] return [perm % kwargs for perm in self.perms_map[method]]

View File

@ -8,7 +8,6 @@ from django.core import validators
from django.db import models from django.db import models
from django.utils.text import capfirst from django.utils.text import capfirst
from rest_framework.compat import clean_manytomany_helptext
from rest_framework.validators import UniqueValidator from rest_framework.validators import UniqueValidator
NUMERIC_FIELD_TYPES = ( NUMERIC_FIELD_TYPES = (
@ -222,7 +221,7 @@ def get_relation_kwargs(field_name, relation_info):
if model_field: if model_field:
if model_field.verbose_name and needs_label(model_field, field_name): if model_field.verbose_name and needs_label(model_field, field_name):
kwargs['label'] = capfirst(model_field.verbose_name) kwargs['label'] = capfirst(model_field.verbose_name)
help_text = clean_manytomany_helptext(model_field.help_text) help_text = model_field.help_text
if help_text: if help_text:
kwargs['help_text'] = help_text kwargs['help_text'] = help_text
if not model_field.editable: if not model_field.editable:

View File

@ -11,7 +11,7 @@ from rest_framework import (
HTTP_HEADER_ENCODING, authentication, generics, permissions, serializers, HTTP_HEADER_ENCODING, authentication, generics, permissions, serializers,
status status
) )
from rest_framework.compat import get_model_name, guardian, unittest from rest_framework.compat import guardian, unittest
from rest_framework.filters import DjangoObjectPermissionsFilter from rest_framework.filters import DjangoObjectPermissionsFilter
from rest_framework.routers import DefaultRouter from rest_framework.routers import DefaultRouter
from rest_framework.test import APIRequestFactory from rest_framework.test import APIRequestFactory
@ -278,7 +278,7 @@ class ObjectPermissionsIntegrationTests(TestCase):
# give everyone model level permissions, as we are not testing those # give everyone model level permissions, as we are not testing those
everyone = Group.objects.create(name='everyone') everyone = Group.objects.create(name='everyone')
model_name = get_model_name(BasicPermModel) model_name = BasicPermModel._meta.model_name
app_label = BasicPermModel._meta.app_label app_label = BasicPermModel._meta.app_label
f = '{0}_{1}'.format f = '{0}_{1}'.format
perms = { perms = {

14
tox.ini
View File

@ -4,15 +4,23 @@ addopts=--tb=short
[tox] [tox]
envlist = envlist =
py27-{lint,docs}, py27-{lint,docs},
{py26,py27,py32,py33,py34}-django{15,16}, {py26,py27,py32,py33,py34}-django16,
{py27,py32,py33,py34}-django{17,18,master} {py27,py32,py33,py34}-django{17,18},
{py27,py34,py35}-django{master}
[testenv] [testenv]
basepython =
py26: python2.6
py27: python2.7
py32: python3.2
py33: python3.3
py34: python3.4
py35: python3.5
commands = ./runtests.py --fast {posargs} --coverage commands = ./runtests.py --fast {posargs} --coverage
setenv = setenv =
PYTHONDONTWRITEBYTECODE=1 PYTHONDONTWRITEBYTECODE=1
deps = deps =
django15: Django==1.5.6 # Should track minimum supported
django16: Django==1.6.3 # Should track minimum supported django16: Django==1.6.3 # Should track minimum supported
django17: Django==1.7.10 # Should track maximum supported django17: Django==1.7.10 # Should track maximum supported
django18: Django==1.8.4 # Should track maximum supported django18: Django==1.8.4 # Should track maximum supported