mirror of
https://github.com/encode/django-rest-framework.git
synced 2024-11-14 05:36:50 +03:00
Remove references to unsupported Django versions in docs and code (#5602)
Per the trove classifiers, DRF only supports Django versions 1.10+. Can drop documentation, code comments, and workarounds for older Django versions.
This commit is contained in:
parent
9c11077cf6
commit
ff556a91fd
|
@ -356,8 +356,6 @@ Corresponds to `django.db.models.fields.DurationField`
|
||||||
The `validated_data` for these fields will contain a `datetime.timedelta` instance.
|
The `validated_data` for these fields will contain a `datetime.timedelta` instance.
|
||||||
The representation is a string following this format `'[DD] [HH:[MM:]]ss[.uuuuuu]'`.
|
The representation is a string following this format `'[DD] [HH:[MM:]]ss[.uuuuuu]'`.
|
||||||
|
|
||||||
**Note:** This field is only available with Django versions >= 1.8.
|
|
||||||
|
|
||||||
**Signature:** `DurationField()`
|
**Signature:** `DurationField()`
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
|
@ -120,10 +120,10 @@ If you're intending to use the browsable API you'll probably also want to add RE
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
...
|
...
|
||||||
url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework'))
|
url(r'^api-auth/', include('rest_framework.urls'))
|
||||||
]
|
]
|
||||||
|
|
||||||
Note that the URL path can be whatever you want, but you must include `'rest_framework.urls'` with the `'rest_framework'` namespace. You may leave out the namespace in Django 1.9+, and REST framework will set it for you.
|
Note that the URL path can be whatever you want.
|
||||||
|
|
||||||
## Example
|
## Example
|
||||||
|
|
||||||
|
|
|
@ -48,8 +48,6 @@ We'll need to add our new `snippets` app and the `rest_framework` app to `INSTAL
|
||||||
'snippets.apps.SnippetsConfig',
|
'snippets.apps.SnippetsConfig',
|
||||||
)
|
)
|
||||||
|
|
||||||
Please note that if you're using Django <1.9, you need to replace `snippets.apps.SnippetsConfig` with `snippets`.
|
|
||||||
|
|
||||||
Okay, we're ready to roll.
|
Okay, we're ready to roll.
|
||||||
|
|
||||||
## Creating a model to work with
|
## Creating a model to work with
|
||||||
|
|
|
@ -142,11 +142,10 @@ Add the following import at the top of the file:
|
||||||
And, at the end of the file, add a pattern to include the login and logout views for the browsable API.
|
And, at the end of the file, add a pattern to include the login and logout views for the browsable API.
|
||||||
|
|
||||||
urlpatterns += [
|
urlpatterns += [
|
||||||
url(r'^api-auth/', include('rest_framework.urls',
|
url(r'^api-auth/', include('rest_framework.urls'),
|
||||||
namespace='rest_framework')),
|
|
||||||
]
|
]
|
||||||
|
|
||||||
The `r'^api-auth/'` part of pattern can actually be whatever URL you want to use. The only restriction is that the included urls must use the `'rest_framework'` namespace. In Django 1.9+, REST framework will set the namespace, so you may leave it out.
|
The `r'^api-auth/'` part of pattern can actually be whatever URL you want to use.
|
||||||
|
|
||||||
Now if you open up the browser again and refresh the page you'll see a 'Login' link in the top right of the page. If you log in as one of the users you created earlier, you'll be able to create code snippets again.
|
Now if you open up the browser again and refresh the page you'll see a 'Login' link in the top right of the page. If you log in as one of the users you created earlier, you'll be able to create code snippets again.
|
||||||
|
|
||||||
|
|
|
@ -20,14 +20,10 @@ class AuthTokenSerializer(serializers.Serializer):
|
||||||
user = authenticate(request=self.context.get('request'),
|
user = authenticate(request=self.context.get('request'),
|
||||||
username=username, password=password)
|
username=username, password=password)
|
||||||
|
|
||||||
if user:
|
# The authenticate call simply returns None for is_active=False
|
||||||
# From Django 1.10 onwards the `authenticate` call simply
|
# users. (Assuming the default ModelBackend authentication
|
||||||
# returns `None` for is_active=False users.
|
# backend.)
|
||||||
# (Assuming the default `ModelBackend` authentication backend.)
|
if not user:
|
||||||
if not user.is_active:
|
|
||||||
msg = _('User account is disabled.')
|
|
||||||
raise serializers.ValidationError(msg, code='authorization')
|
|
||||||
else:
|
|
||||||
msg = _('Unable to log in with provided credentials.')
|
msg = _('Unable to log in with provided credentials.')
|
||||||
raise serializers.ValidationError(msg, code='authorization')
|
raise serializers.ValidationError(msg, code='authorization')
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -666,7 +666,7 @@ class BrowsableAPIRenderer(BaseRenderer):
|
||||||
paginator = None
|
paginator = None
|
||||||
|
|
||||||
csrf_cookie_name = settings.CSRF_COOKIE_NAME
|
csrf_cookie_name = settings.CSRF_COOKIE_NAME
|
||||||
csrf_header_name = getattr(settings, 'CSRF_HEADER_NAME', 'HTTP_X_CSRFToken') # Fallback for Django 1.8
|
csrf_header_name = settings.CSRF_HEADER_NAME
|
||||||
if csrf_header_name.startswith('HTTP_'):
|
if csrf_header_name.startswith('HTTP_'):
|
||||||
csrf_header_name = csrf_header_name[5:]
|
csrf_header_name = csrf_header_name[5:]
|
||||||
csrf_header_name = csrf_header_name.replace('_', '-')
|
csrf_header_name = csrf_header_name.replace('_', '-')
|
||||||
|
|
|
@ -6,11 +6,10 @@ your API requires authentication:
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
...
|
...
|
||||||
url(r'^auth/', include('rest_framework.urls', namespace='rest_framework'))
|
url(r'^auth/', include('rest_framework.urls'))
|
||||||
]
|
]
|
||||||
|
|
||||||
In Django versions older than 1.9, the urls must be namespaced as 'rest_framework',
|
You should make sure your authentication settings include `SessionAuthentication`.
|
||||||
and you should make sure your authentication settings include `SessionAuthentication`.
|
|
||||||
"""
|
"""
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
|
|
@ -105,18 +105,13 @@ def _get_reverse_relationships(opts):
|
||||||
"""
|
"""
|
||||||
Returns an `OrderedDict` of field names to `RelationInfo`.
|
Returns an `OrderedDict` of field names to `RelationInfo`.
|
||||||
"""
|
"""
|
||||||
# Note that we have a hack here to handle internal API differences for
|
|
||||||
# this internal API across Django 1.7 -> Django 1.8.
|
|
||||||
# See: https://code.djangoproject.com/ticket/24208
|
|
||||||
|
|
||||||
reverse_relations = OrderedDict()
|
reverse_relations = OrderedDict()
|
||||||
all_related_objects = [r for r in opts.related_objects if not r.field.many_to_many]
|
all_related_objects = [r for r in opts.related_objects if not r.field.many_to_many]
|
||||||
for relation in all_related_objects:
|
for relation in all_related_objects:
|
||||||
accessor_name = relation.get_accessor_name()
|
accessor_name = relation.get_accessor_name()
|
||||||
related = getattr(relation, 'related_model', relation.model)
|
|
||||||
reverse_relations[accessor_name] = RelationInfo(
|
reverse_relations[accessor_name] = RelationInfo(
|
||||||
model_field=None,
|
model_field=None,
|
||||||
related_model=related,
|
related_model=relation.related_model,
|
||||||
to_many=relation.field.remote_field.multiple,
|
to_many=relation.field.remote_field.multiple,
|
||||||
to_field=_get_to_field(relation.field),
|
to_field=_get_to_field(relation.field),
|
||||||
has_through_model=False,
|
has_through_model=False,
|
||||||
|
@ -127,10 +122,9 @@ def _get_reverse_relationships(opts):
|
||||||
all_related_many_to_many_objects = [r for r in opts.related_objects if r.field.many_to_many]
|
all_related_many_to_many_objects = [r for r in opts.related_objects if r.field.many_to_many]
|
||||||
for relation in all_related_many_to_many_objects:
|
for relation in all_related_many_to_many_objects:
|
||||||
accessor_name = relation.get_accessor_name()
|
accessor_name = relation.get_accessor_name()
|
||||||
related = getattr(relation, 'related_model', relation.model)
|
|
||||||
reverse_relations[accessor_name] = RelationInfo(
|
reverse_relations[accessor_name] = RelationInfo(
|
||||||
model_field=None,
|
model_field=None,
|
||||||
related_model=related,
|
related_model=relation.related_model,
|
||||||
to_many=True,
|
to_many=True,
|
||||||
# manytomany do not have to_fields
|
# manytomany do not have to_fields
|
||||||
to_field=None,
|
to_field=None,
|
||||||
|
|
|
@ -120,13 +120,12 @@ class DBTransactionAPIExceptionTests(TestCase):
|
||||||
Transaction is rollbacked by our transaction atomic block.
|
Transaction is rollbacked by our transaction atomic block.
|
||||||
"""
|
"""
|
||||||
request = factory.post('/')
|
request = factory.post('/')
|
||||||
num_queries = (4 if getattr(connection.features,
|
num_queries = 4 if connection.features.can_release_savepoints else 3
|
||||||
'can_release_savepoints', False) else 3)
|
|
||||||
with self.assertNumQueries(num_queries):
|
with self.assertNumQueries(num_queries):
|
||||||
# 1 - begin savepoint
|
# 1 - begin savepoint
|
||||||
# 2 - insert
|
# 2 - insert
|
||||||
# 3 - rollback savepoint
|
# 3 - rollback savepoint
|
||||||
# 4 - release savepoint (django>=1.8 only)
|
# 4 - release savepoint
|
||||||
with transaction.atomic():
|
with transaction.atomic():
|
||||||
response = self.view(request)
|
response = self.view(request)
|
||||||
assert transaction.get_rollback()
|
assert transaction.get_rollback()
|
||||||
|
|
|
@ -5,7 +5,6 @@ import unittest
|
||||||
import uuid
|
import uuid
|
||||||
from decimal import ROUND_DOWN, ROUND_UP, Decimal
|
from decimal import ROUND_DOWN, ROUND_UP, Decimal
|
||||||
|
|
||||||
import django
|
|
||||||
import pytest
|
import pytest
|
||||||
from django.http import QueryDict
|
from django.http import QueryDict
|
||||||
from django.test import TestCase, override_settings
|
from django.test import TestCase, override_settings
|
||||||
|
@ -1197,11 +1196,6 @@ class TestDateTimeField(FieldValues):
|
||||||
field = serializers.DateTimeField(default_timezone=utc)
|
field = serializers.DateTimeField(default_timezone=utc)
|
||||||
|
|
||||||
|
|
||||||
if django.VERSION[:2] <= (1, 8):
|
|
||||||
# Doesn't raise an error on earlier versions of Django
|
|
||||||
TestDateTimeField.invalid_inputs.pop('2018-08-16 22:00-24:00')
|
|
||||||
|
|
||||||
|
|
||||||
class TestCustomInputFormatDateTimeField(FieldValues):
|
class TestCustomInputFormatDateTimeField(FieldValues):
|
||||||
"""
|
"""
|
||||||
Valid and invalid values for `DateTimeField` with a custom input format.
|
Valid and invalid values for `DateTimeField` with a custom input format.
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
import datetime
|
import datetime
|
||||||
import unittest
|
|
||||||
|
|
||||||
import django
|
|
||||||
import pytest
|
import pytest
|
||||||
from django.core.exceptions import ImproperlyConfigured
|
from django.core.exceptions import ImproperlyConfigured
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
@ -291,7 +289,6 @@ class SearchFilterToManyTests(TestCase):
|
||||||
Entry.objects.create(blog=b2, headline='Something unrelated', pub_date=datetime.date(1979, 1, 1))
|
Entry.objects.create(blog=b2, headline='Something unrelated', pub_date=datetime.date(1979, 1, 1))
|
||||||
Entry.objects.create(blog=b2, headline='Retrospective on Lennon', pub_date=datetime.date(1990, 6, 1))
|
Entry.objects.create(blog=b2, headline='Retrospective on Lennon', pub_date=datetime.date(1990, 6, 1))
|
||||||
|
|
||||||
@unittest.skipIf(django.VERSION < (1, 9), "Django 1.8 does not support transforms")
|
|
||||||
def test_multiple_filter_conditions(self):
|
def test_multiple_filter_conditions(self):
|
||||||
class SearchListView(generics.ListAPIView):
|
class SearchListView(generics.ListAPIView):
|
||||||
queryset = Blog.objects.all()
|
queryset = Blog.objects.all()
|
||||||
|
|
Loading…
Reference in New Issue
Block a user