mirror of
https://github.com/encode/django-rest-framework.git
synced 2024-11-30 13:34:00 +03:00
Merge pull request #3421 from carltongibson/supported-versions-2
Drop Django 1.5
This commit is contained in:
commit
5b2b675a21
11
.travis.yml
11
.travis.yml
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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']
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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):
|
||||||
|
|
|
@ -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]]
|
||||||
|
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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
14
tox.ini
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue
Block a user