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

Adjust Supported Python/Django Versions #3421

Merged
merged 9 commits into from
Sep 22, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 2 additions & 9 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,23 +18,16 @@ env:
- TOX_ENV=py32-django16
- TOX_ENV=py27-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=py32-djangomaster
- TOX_ENV=py33-djangomaster
- TOX_ENV=py34-djangomaster
- TOX_ENV=py35-djangomaster

matrix:
fast_finish: true
allow_failures:
- env: TOX_ENV=py27-djangomaster
- env: TOX_ENV=py32-djangomaster
- env: TOX_ENV=py33-djangomaster
- env: TOX_ENV=py34-djangomaster
- env: TOX_ENV=py35-djangomaster

install:
- pip install tox
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ There is a live example API for testing purposes, [available here][sandbox].
# Requirements

* 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

Expand Down
11 changes: 10 additions & 1 deletion docs/topics/release-notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.3
Expand Down Expand Up @@ -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



<!-- 3.0.0 -->
[gh3421]: https://github.com/tomchristie/django-rest-framework/pulls/3421

45 changes: 0 additions & 45 deletions rest_framework/compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,17 +106,6 @@ def distinct(queryset, base):
except ImportError:
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
# Fixes (#1712). We keep the try/except for the test suite.
guardian = None
Expand All @@ -127,14 +116,6 @@ def clean_manytomany_helptext(text):
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+
if django.VERSION >= (1, 8):
from django.core.validators import MinValueValidator, MaxValueValidator
Expand Down Expand Up @@ -170,32 +151,6 @@ def __init__(self, *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
if 'patch' not in View.http_method_names:
View.http_method_names = View.http_method_names + ['patch']
Expand Down
10 changes: 6 additions & 4 deletions rest_framework/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@
from django.conf import settings
from django.core.exceptions import ValidationError as DjangoValidationError
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 ImageField as DjangoImageField
from django.utils import six, timezone
Expand All @@ -23,9 +25,9 @@

from rest_framework import ISO_8601
from rest_framework.compat import (
EmailValidator, MaxLengthValidator, MaxValueValidator, MinLengthValidator,
MinValueValidator, OrderedDict, URLValidator, duration_string,
parse_duration, unicode_repr, unicode_to_repr
MaxLengthValidator, MaxValueValidator, MinLengthValidator,
MinValueValidator, OrderedDict, duration_string, parse_duration,
unicode_repr, unicode_to_repr
)
from rest_framework.exceptions import ValidationError
from rest_framework.settings import api_settings
Expand Down
6 changes: 2 additions & 4 deletions rest_framework/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,7 @@
from django.db import models
from django.utils import six

from rest_framework.compat import (
distinct, django_filters, get_model_name, guardian
)
from rest_framework.compat import distinct, django_filters, guardian
from rest_framework.settings import api_settings

FilterSet = django_filters and django_filters.FilterSet or None
Expand Down Expand Up @@ -202,7 +200,7 @@ def filter_queryset(self, request, queryset, view):
model_cls = queryset.model
kwargs = {
'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
if guardian.VERSION >= (1, 3):
Expand Down
6 changes: 2 additions & 4 deletions rest_framework/permissions.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@

from django.http import Http404

from rest_framework.compat import get_model_name

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


Expand Down Expand Up @@ -104,7 +102,7 @@ def get_required_permissions(self, method, model_cls):
"""
kwargs = {
'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]]

Expand Down Expand Up @@ -166,7 +164,7 @@ class DjangoObjectPermissions(DjangoModelPermissions):
def get_required_object_permissions(self, method, model_cls):
kwargs = {
'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]]

Expand Down
3 changes: 1 addition & 2 deletions rest_framework/utils/field_mapping.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
from django.db import models
from django.utils.text import capfirst

from rest_framework.compat import clean_manytomany_helptext
from rest_framework.validators import UniqueValidator

NUMERIC_FIELD_TYPES = (
Expand Down Expand Up @@ -222,7 +221,7 @@ def get_relation_kwargs(field_name, relation_info):
if model_field:
if model_field.verbose_name and needs_label(model_field, field_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:
kwargs['help_text'] = help_text
if not model_field.editable:
Expand Down
4 changes: 2 additions & 2 deletions tests/test_permissions.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
HTTP_HEADER_ENCODING, authentication, generics, permissions, serializers,
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.routers import DefaultRouter
from rest_framework.test import APIRequestFactory
Expand Down Expand Up @@ -278,7 +278,7 @@ def setUp(self):

# give everyone model level permissions, as we are not testing those
everyone = Group.objects.create(name='everyone')
model_name = get_model_name(BasicPermModel)
model_name = BasicPermModel._meta.model_name
app_label = BasicPermModel._meta.app_label
f = '{0}_{1}'.format
perms = {
Expand Down
14 changes: 11 additions & 3 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,23 @@ addopts=--tb=short
[tox]
envlist =
py27-{lint,docs},
{py26,py27,py32,py33,py34}-django{15,16},
{py27,py32,py33,py34}-django{17,18,master}
{py26,py27,py32,py33,py34}-django16,
{py27,py32,py33,py34}-django{17,18},
{py27,py34,py35}-django{master}

[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
setenv =
PYTHONDONTWRITEBYTECODE=1
deps =
django15: Django==1.5.6 # Should track minimum supported
django16: Django==1.6.3 # Should track minimum supported
django17: Django==1.7.10 # Should track maximum supported
django18: Django==1.8.4 # Should track maximum supported
Expand Down