mirror of
				https://github.com/encode/django-rest-framework.git
				synced 2025-11-04 09:57:55 +03:00 
			
		
		
		
	Merge branch 'master' of github.com:tomchristie/django-rest-framework
This commit is contained in:
		
						commit
						222f80f340
					
				| 
						 | 
					@ -261,7 +261,7 @@ Framework.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
For support please see the [REST framework discussion group][group], try the  `#restframework` channel on `irc.freenode.net`, search [the IRC archives][botbot], or raise a  question on [Stack Overflow][stack-overflow], making sure to include the ['django-rest-framework'][django-rest-framework-tag] tag.
 | 
					For support please see the [REST framework discussion group][group], try the  `#restframework` channel on `irc.freenode.net`, search [the IRC archives][botbot], or raise a  question on [Stack Overflow][stack-overflow], making sure to include the ['django-rest-framework'][django-rest-framework-tag] tag.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[Paid support is available][paid-support] from [DabApps][dabapps], and can include work on REST framework core, or support with building your REST framework API.  Please [contact DabApps][contact-dabapps] if you'd like to discuss commercial support options.
 | 
					For priority support please sign up for a [professional or premium sponsorship plan](https://fund.django-rest-framework.org/topics/funding/).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
For updates on REST framework development, you may also want to follow [the author][twitter] on Twitter.
 | 
					For updates on REST framework development, you may also want to follow [the author][twitter] on Twitter.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -308,7 +308,7 @@ Our professional and premium plans also include **priority support**. At any tim
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Once you've signed up I'll contact you via email and arrange your ad placements on the site.
 | 
					Once you've signed up I'll contact you via email and arrange your ad placements on the site.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
For further enquires please contact <a href=mailto:tom@tomchristie.com>tom@tomchristie.com</a>.
 | 
					For further enquires please contact <a href=mailto:funding@django-rest-framework.org>funding@django-rest-framework.org</a>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
---
 | 
					---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -17,11 +17,6 @@ from django.template import Context, RequestContext, Template
 | 
				
			||||||
from django.utils import six
 | 
					from django.utils import six
 | 
				
			||||||
from django.views.generic import View
 | 
					from django.views.generic import View
 | 
				
			||||||
 | 
					
 | 
				
			||||||
try:
 | 
					 | 
				
			||||||
    import importlib  # Available in Python 3.1+
 | 
					 | 
				
			||||||
except ImportError:
 | 
					 | 
				
			||||||
    from django.utils import importlib  # Will be removed in Django 1.9
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
try:
 | 
					try:
 | 
				
			||||||
    from django.urls import (
 | 
					    from django.urls import (
 | 
				
			||||||
| 
						 | 
					@ -312,3 +307,10 @@ def set_many(instance, field, value):
 | 
				
			||||||
    else:
 | 
					    else:
 | 
				
			||||||
        field = getattr(instance, field)
 | 
					        field = getattr(instance, field)
 | 
				
			||||||
        field.set(value)
 | 
					        field.set(value)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def include(module, namespace=None, app_name=None):
 | 
				
			||||||
 | 
					    from django.conf.urls import include
 | 
				
			||||||
 | 
					    if django.VERSION < (1,9):
 | 
				
			||||||
 | 
					        return include(module, namespace, app_name)
 | 
				
			||||||
 | 
					    else:
 | 
				
			||||||
 | 
					        return include((module, app_name), namespace)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -18,13 +18,13 @@ REST framework settings, checking for user settings first, then falling
 | 
				
			||||||
back to the defaults.
 | 
					back to the defaults.
 | 
				
			||||||
"""
 | 
					"""
 | 
				
			||||||
from __future__ import unicode_literals
 | 
					from __future__ import unicode_literals
 | 
				
			||||||
 | 
					from importlib import import_module
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from django.conf import settings
 | 
					from django.conf import settings
 | 
				
			||||||
from django.test.signals import setting_changed
 | 
					from django.test.signals import setting_changed
 | 
				
			||||||
from django.utils import six
 | 
					from django.utils import six
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from rest_framework import ISO_8601
 | 
					from rest_framework import ISO_8601
 | 
				
			||||||
from rest_framework.compat import importlib
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
DEFAULTS = {
 | 
					DEFAULTS = {
 | 
				
			||||||
    # Base API policies
 | 
					    # Base API policies
 | 
				
			||||||
| 
						 | 
					@ -174,7 +174,7 @@ def import_from_string(val, setting_name):
 | 
				
			||||||
        # Nod to tastypie's use of importlib.
 | 
					        # Nod to tastypie's use of importlib.
 | 
				
			||||||
        parts = val.split('.')
 | 
					        parts = val.split('.')
 | 
				
			||||||
        module_path, class_name = '.'.join(parts[:-1]), parts[-1]
 | 
					        module_path, class_name = '.'.join(parts[:-1]), parts[-1]
 | 
				
			||||||
        module = importlib.import_module(module_path)
 | 
					        module = import_module(module_path)
 | 
				
			||||||
        return getattr(module, class_name)
 | 
					        return getattr(module, class_name)
 | 
				
			||||||
    except (ImportError, AttributeError) as e:
 | 
					    except (ImportError, AttributeError) as e:
 | 
				
			||||||
        msg = "Could not import '%s' for API setting '%s'. %s: %s." % (val, setting_name, e.__class__.__name__, e)
 | 
					        msg = "Could not import '%s' for API setting '%s'. %s: %s." % (val, setting_name, e.__class__.__name__, e)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -114,7 +114,7 @@ if requests is not None:
 | 
				
			||||||
            self.mount('https://', adapter)
 | 
					            self.mount('https://', adapter)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        def request(self, method, url, *args, **kwargs):
 | 
					        def request(self, method, url, *args, **kwargs):
 | 
				
			||||||
            if ':' not in url:
 | 
					            if not url.startswith('http'):
 | 
				
			||||||
                raise ValueError('Missing "http:" or "https:". Use a fully qualified URL, eg "http://testserver%s"' % url)
 | 
					                raise ValueError('Missing "http:" or "https:". Use a fully qualified URL, eg "http://testserver%s"' % url)
 | 
				
			||||||
            return super(RequestsClient, self).request(method, url, *args, **kwargs)
 | 
					            return super(RequestsClient, self).request(method, url, *args, **kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,8 +1,8 @@
 | 
				
			||||||
from __future__ import unicode_literals
 | 
					from __future__ import unicode_literals
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from django.conf.urls import include, url
 | 
					from django.conf.urls import url
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from rest_framework.compat import RegexURLResolver
 | 
					from rest_framework.compat import RegexURLResolver, include
 | 
				
			||||||
from rest_framework.settings import api_settings
 | 
					from rest_framework.settings import api_settings
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -32,23 +32,18 @@ def dedent(content):
 | 
				
			||||||
    unindented text on the initial line.
 | 
					    unindented text on the initial line.
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    content = force_text(content)
 | 
					    content = force_text(content)
 | 
				
			||||||
    whitespace_counts = [
 | 
					    lines = [line for line in content.splitlines()[1:] if line.lstrip()]
 | 
				
			||||||
        len(line) - len(line.lstrip(' '))
 | 
					 | 
				
			||||||
        for line in content.splitlines()[1:] if line.lstrip()
 | 
					 | 
				
			||||||
    ]
 | 
					 | 
				
			||||||
    tab_counts = [
 | 
					 | 
				
			||||||
        len(line) - len(line.lstrip('\t'))
 | 
					 | 
				
			||||||
        for line in content.splitlines()[1:] if line.lstrip()
 | 
					 | 
				
			||||||
    ]
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # unindent the content if needed
 | 
					    # unindent the content if needed
 | 
				
			||||||
 | 
					    if lines:
 | 
				
			||||||
 | 
					        whitespace_counts = min([len(line) - len(line.lstrip(' ')) for line in lines])
 | 
				
			||||||
 | 
					        tab_counts = min([len(line) - len(line.lstrip('\t')) for line in lines])
 | 
				
			||||||
        if whitespace_counts:
 | 
					        if whitespace_counts:
 | 
				
			||||||
        whitespace_pattern = '^' + (' ' * min(whitespace_counts))
 | 
					            whitespace_pattern = '^' + (' ' * whitespace_counts)
 | 
				
			||||||
            content = re.sub(re.compile(whitespace_pattern, re.MULTILINE), '', content)
 | 
					            content = re.sub(re.compile(whitespace_pattern, re.MULTILINE), '', content)
 | 
				
			||||||
        elif tab_counts:
 | 
					        elif tab_counts:
 | 
				
			||||||
        whitespace_pattern = '^' + ('\t' * min(whitespace_counts))
 | 
					            whitespace_pattern = '^' + ('\t' * tab_counts)
 | 
				
			||||||
            content = re.sub(re.compile(whitespace_pattern, re.MULTILINE), '', content)
 | 
					            content = re.sub(re.compile(whitespace_pattern, re.MULTILINE), '', content)
 | 
				
			||||||
 | 
					 | 
				
			||||||
    return content.strip()
 | 
					    return content.strip()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -124,4 +124,8 @@ class TestViewNamesAndDescriptions(TestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def test_dedent_tabs():
 | 
					def test_dedent_tabs():
 | 
				
			||||||
    assert dedent("\tfirst string\n\n\tsecond string") == 'first string\n\n\tsecond string'
 | 
					    result = 'first string\n\nsecond string'
 | 
				
			||||||
 | 
					    assert dedent("    first string\n\n    second string") == result
 | 
				
			||||||
 | 
					    assert dedent("first string\n\n    second string") == result
 | 
				
			||||||
 | 
					    assert dedent("\tfirst string\n\n\tsecond string") == result
 | 
				
			||||||
 | 
					    assert dedent("first string\n\n\tsecond string") == result
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -547,3 +547,94 @@ class TestGuardedQueryset(TestCase):
 | 
				
			||||||
        request = factory.get('/')
 | 
					        request = factory.get('/')
 | 
				
			||||||
        with pytest.raises(RuntimeError):
 | 
					        with pytest.raises(RuntimeError):
 | 
				
			||||||
            view(request).render()
 | 
					            view(request).render()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ApiViewsTests(TestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_create_api_view_post(self):
 | 
				
			||||||
 | 
					        class MockCreateApiView(generics.CreateAPIView):
 | 
				
			||||||
 | 
					            def create(self, request, *args, **kwargs):
 | 
				
			||||||
 | 
					                self.called = True
 | 
				
			||||||
 | 
					                self.call_args = (request, args, kwargs)
 | 
				
			||||||
 | 
					        view = MockCreateApiView()
 | 
				
			||||||
 | 
					        data = ('test request', ('test arg',), {'test_kwarg': 'test'})
 | 
				
			||||||
 | 
					        view.post('test request', 'test arg', test_kwarg='test')
 | 
				
			||||||
 | 
					        assert view.called is True
 | 
				
			||||||
 | 
					        assert view.call_args == data
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_destroy_api_view_delete(self):
 | 
				
			||||||
 | 
					        class MockDestroyApiView(generics.DestroyAPIView):
 | 
				
			||||||
 | 
					            def destroy(self, request, *args, **kwargs):
 | 
				
			||||||
 | 
					                self.called = True
 | 
				
			||||||
 | 
					                self.call_args = (request, args, kwargs)
 | 
				
			||||||
 | 
					        view = MockDestroyApiView()
 | 
				
			||||||
 | 
					        data = ('test request', ('test arg',), {'test_kwarg': 'test'})
 | 
				
			||||||
 | 
					        view.delete('test request', 'test arg', test_kwarg='test')
 | 
				
			||||||
 | 
					        assert view.called is True
 | 
				
			||||||
 | 
					        assert view.call_args == data
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_update_api_view_partial_update(self):
 | 
				
			||||||
 | 
					        class MockUpdateApiView(generics.UpdateAPIView):
 | 
				
			||||||
 | 
					            def partial_update(self, request, *args, **kwargs):
 | 
				
			||||||
 | 
					                self.called = True
 | 
				
			||||||
 | 
					                self.call_args = (request, args, kwargs)
 | 
				
			||||||
 | 
					        view = MockUpdateApiView()
 | 
				
			||||||
 | 
					        data = ('test request', ('test arg',), {'test_kwarg': 'test'})
 | 
				
			||||||
 | 
					        view.patch('test request', 'test arg', test_kwarg='test')
 | 
				
			||||||
 | 
					        assert view.called is True
 | 
				
			||||||
 | 
					        assert view.call_args == data
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_retrieve_update_api_view_get(self):
 | 
				
			||||||
 | 
					        class MockRetrieveUpdateApiView(generics.RetrieveUpdateAPIView):
 | 
				
			||||||
 | 
					            def retrieve(self, request, *args, **kwargs):
 | 
				
			||||||
 | 
					                self.called = True
 | 
				
			||||||
 | 
					                self.call_args = (request, args, kwargs)
 | 
				
			||||||
 | 
					        view = MockRetrieveUpdateApiView()
 | 
				
			||||||
 | 
					        data = ('test request', ('test arg',), {'test_kwarg': 'test'})
 | 
				
			||||||
 | 
					        view.get('test request', 'test arg', test_kwarg='test')
 | 
				
			||||||
 | 
					        assert view.called is True
 | 
				
			||||||
 | 
					        assert view.call_args == data
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_retrieve_update_api_view_put(self):
 | 
				
			||||||
 | 
					        class MockRetrieveUpdateApiView(generics.RetrieveUpdateAPIView):
 | 
				
			||||||
 | 
					            def update(self, request, *args, **kwargs):
 | 
				
			||||||
 | 
					                self.called = True
 | 
				
			||||||
 | 
					                self.call_args = (request, args, kwargs)
 | 
				
			||||||
 | 
					        view = MockRetrieveUpdateApiView()
 | 
				
			||||||
 | 
					        data = ('test request', ('test arg',), {'test_kwarg': 'test'})
 | 
				
			||||||
 | 
					        view.put('test request', 'test arg', test_kwarg='test')
 | 
				
			||||||
 | 
					        assert view.called is True
 | 
				
			||||||
 | 
					        assert view.call_args == data
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_retrieve_update_api_view_patch(self):
 | 
				
			||||||
 | 
					        class MockRetrieveUpdateApiView(generics.RetrieveUpdateAPIView):
 | 
				
			||||||
 | 
					            def partial_update(self, request, *args, **kwargs):
 | 
				
			||||||
 | 
					                self.called = True
 | 
				
			||||||
 | 
					                self.call_args = (request, args, kwargs)
 | 
				
			||||||
 | 
					        view = MockRetrieveUpdateApiView()
 | 
				
			||||||
 | 
					        data = ('test request', ('test arg',), {'test_kwarg': 'test'})
 | 
				
			||||||
 | 
					        view.patch('test request', 'test arg', test_kwarg='test')
 | 
				
			||||||
 | 
					        assert view.called is True
 | 
				
			||||||
 | 
					        assert view.call_args == data
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_retrieve_destroy_api_view_get(self):
 | 
				
			||||||
 | 
					        class MockRetrieveDestroyUApiView(generics.RetrieveDestroyAPIView):
 | 
				
			||||||
 | 
					            def retrieve(self, request, *args, **kwargs):
 | 
				
			||||||
 | 
					                self.called = True
 | 
				
			||||||
 | 
					                self.call_args = (request, args, kwargs)
 | 
				
			||||||
 | 
					        view = MockRetrieveDestroyUApiView()
 | 
				
			||||||
 | 
					        data = ('test request', ('test arg',), {'test_kwarg': 'test'})
 | 
				
			||||||
 | 
					        view.get('test request', 'test arg', test_kwarg='test')
 | 
				
			||||||
 | 
					        assert view.called is True
 | 
				
			||||||
 | 
					        assert view.call_args == data
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_retrieve_destroy_api_view_delete(self):
 | 
				
			||||||
 | 
					        class MockRetrieveDestroyUApiView(generics.RetrieveDestroyAPIView):
 | 
				
			||||||
 | 
					            def destroy(self, request, *args, **kwargs):
 | 
				
			||||||
 | 
					                self.called = True
 | 
				
			||||||
 | 
					                self.call_args = (request, args, kwargs)
 | 
				
			||||||
 | 
					        view = MockRetrieveDestroyUApiView()
 | 
				
			||||||
 | 
					        data = ('test request', ('test arg',), {'test_kwarg': 'test'})
 | 
				
			||||||
 | 
					        view.delete('test request', 'test arg', test_kwarg='test')
 | 
				
			||||||
 | 
					        assert view.called is True
 | 
				
			||||||
 | 
					        assert view.call_args == data
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -370,6 +370,13 @@ class TestLimitOffset:
 | 
				
			||||||
        assert self.pagination.display_page_controls
 | 
					        assert self.pagination.display_page_controls
 | 
				
			||||||
        assert isinstance(self.pagination.to_html(), type(''))
 | 
					        assert isinstance(self.pagination.to_html(), type(''))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_pagination_not_applied_if_limit_or_default_limit_not_set(self):
 | 
				
			||||||
 | 
					        class MockPagination(pagination.LimitOffsetPagination):
 | 
				
			||||||
 | 
					            default_limit = None
 | 
				
			||||||
 | 
					        request = Request(factory.get('/'))
 | 
				
			||||||
 | 
					        queryset = MockPagination().paginate_queryset(self.queryset, request)
 | 
				
			||||||
 | 
					        assert queryset is None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_single_offset(self):
 | 
					    def test_single_offset(self):
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        When the offset is not a multiple of the limit we get some edge cases:
 | 
					        When the offset is not a multiple of the limit we get some edge cases:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,12 +4,13 @@ import json
 | 
				
			||||||
from collections import namedtuple
 | 
					from collections import namedtuple
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import pytest
 | 
					import pytest
 | 
				
			||||||
from django.conf.urls import include, url
 | 
					from django.conf.urls import url
 | 
				
			||||||
from django.core.exceptions import ImproperlyConfigured
 | 
					from django.core.exceptions import ImproperlyConfigured
 | 
				
			||||||
from django.db import models
 | 
					from django.db import models
 | 
				
			||||||
from django.test import TestCase, override_settings
 | 
					from django.test import TestCase, override_settings
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from rest_framework import permissions, serializers, viewsets
 | 
					from rest_framework import permissions, serializers, viewsets
 | 
				
			||||||
 | 
					from rest_framework.compat import include
 | 
				
			||||||
from rest_framework.decorators import detail_route, list_route
 | 
					from rest_framework.decorators import detail_route, list_route
 | 
				
			||||||
from rest_framework.response import Response
 | 
					from rest_framework.response import Response
 | 
				
			||||||
from rest_framework.routers import DefaultRouter, SimpleRouter
 | 
					from rest_framework.routers import DefaultRouter, SimpleRouter
 | 
				
			||||||
| 
						 | 
					@ -81,7 +82,7 @@ empty_prefix_urls = [
 | 
				
			||||||
 | 
					
 | 
				
			||||||
urlpatterns = [
 | 
					urlpatterns = [
 | 
				
			||||||
    url(r'^non-namespaced/', include(namespaced_router.urls)),
 | 
					    url(r'^non-namespaced/', include(namespaced_router.urls)),
 | 
				
			||||||
    url(r'^namespaced/', include(namespaced_router.urls, namespace='example')),
 | 
					    url(r'^namespaced/', include(namespaced_router.urls, namespace='example', app_name='example')),
 | 
				
			||||||
    url(r'^example/', include(notes_router.urls)),
 | 
					    url(r'^example/', include(notes_router.urls)),
 | 
				
			||||||
    url(r'^example2/', include(kwarged_notes_router.urls)),
 | 
					    url(r'^example2/', include(kwarged_notes_router.urls)),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -159,6 +159,32 @@ class TestBaseSerializer:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.Serializer = ExampleSerializer
 | 
					        self.Serializer = ExampleSerializer
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_abstract_methods_raise_proper_errors(self):
 | 
				
			||||||
 | 
					        serializer = serializers.BaseSerializer()
 | 
				
			||||||
 | 
					        with pytest.raises(NotImplementedError):
 | 
				
			||||||
 | 
					            serializer.to_internal_value(None)
 | 
				
			||||||
 | 
					        with pytest.raises(NotImplementedError):
 | 
				
			||||||
 | 
					            serializer.to_representation(None)
 | 
				
			||||||
 | 
					        with pytest.raises(NotImplementedError):
 | 
				
			||||||
 | 
					            serializer.update(None, None)
 | 
				
			||||||
 | 
					        with pytest.raises(NotImplementedError):
 | 
				
			||||||
 | 
					            serializer.create(None)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_access_to_data_attribute_before_validation_raises_error(self):
 | 
				
			||||||
 | 
					        serializer = serializers.BaseSerializer(data={'foo': 'bar'})
 | 
				
			||||||
 | 
					        with pytest.raises(AssertionError):
 | 
				
			||||||
 | 
					            serializer.data
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_access_to_errors_attribute_before_validation_raises_error(self):
 | 
				
			||||||
 | 
					        serializer = serializers.BaseSerializer(data={'foo': 'bar'})
 | 
				
			||||||
 | 
					        with pytest.raises(AssertionError):
 | 
				
			||||||
 | 
					            serializer.errors
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_access_to_validated_data_attribute_before_validation_raises_error(self):
 | 
				
			||||||
 | 
					        serializer = serializers.BaseSerializer(data={'foo': 'bar'})
 | 
				
			||||||
 | 
					        with pytest.raises(AssertionError):
 | 
				
			||||||
 | 
					            serializer.validated_data
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_serialize_instance(self):
 | 
					    def test_serialize_instance(self):
 | 
				
			||||||
        instance = {'id': 1, 'name': 'tom', 'domain': 'example.com'}
 | 
					        instance = {'id': 1, 'name': 'tom', 'domain': 'example.com'}
 | 
				
			||||||
        serializer = self.Serializer(instance)
 | 
					        serializer = self.Serializer(instance)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,8 +1,9 @@
 | 
				
			||||||
import pytest
 | 
					import pytest
 | 
				
			||||||
from django.conf.urls import include, url
 | 
					from django.conf.urls import url
 | 
				
			||||||
from django.test import override_settings
 | 
					from django.test import override_settings
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from rest_framework import serializers, status, versioning
 | 
					from rest_framework import serializers, status, versioning
 | 
				
			||||||
 | 
					from rest_framework.compat import include
 | 
				
			||||||
from rest_framework.decorators import APIView
 | 
					from rest_framework.decorators import APIView
 | 
				
			||||||
from rest_framework.relations import PKOnlyObject
 | 
					from rest_framework.relations import PKOnlyObject
 | 
				
			||||||
from rest_framework.response import Response
 | 
					from rest_framework.response import Response
 | 
				
			||||||
| 
						 | 
					@ -170,7 +171,7 @@ class TestURLReversing(URLPatternsTestCase):
 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    urlpatterns = [
 | 
					    urlpatterns = [
 | 
				
			||||||
        url(r'^v1/', include(included, namespace='v1')),
 | 
					        url(r'^v1/', include(included, namespace='v1', app_name='v1')),
 | 
				
			||||||
        url(r'^another/$', dummy_view, name='another'),
 | 
					        url(r'^another/$', dummy_view, name='another'),
 | 
				
			||||||
        url(r'^(?P<version>[v1|v2]+)/another/$', dummy_view, name='another'),
 | 
					        url(r'^(?P<version>[v1|v2]+)/another/$', dummy_view, name='another'),
 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
| 
						 | 
					@ -335,8 +336,8 @@ class TestHyperlinkedRelatedField(URLPatternsTestCase):
 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    urlpatterns = [
 | 
					    urlpatterns = [
 | 
				
			||||||
        url(r'^v1/', include(included, namespace='v1')),
 | 
					        url(r'^v1/', include(included, namespace='v1', app_name='v1')),
 | 
				
			||||||
        url(r'^v2/', include(included, namespace='v2'))
 | 
					        url(r'^v2/', include(included, namespace='v2', app_name='v2'))
 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def setUp(self):
 | 
					    def setUp(self):
 | 
				
			||||||
| 
						 | 
					@ -367,7 +368,7 @@ class TestNamespaceVersioningHyperlinkedRelatedFieldScheme(URLPatternsTestCase):
 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
    included = [
 | 
					    included = [
 | 
				
			||||||
        url(r'^namespaced/(?P<pk>\d+)/$', dummy_pk_view, name='namespaced'),
 | 
					        url(r'^namespaced/(?P<pk>\d+)/$', dummy_pk_view, name='namespaced'),
 | 
				
			||||||
        url(r'^nested/', include(nested, namespace='nested-namespace'))
 | 
					        url(r'^nested/', include(nested, namespace='nested-namespace', app_name='nested-namespace'))
 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    urlpatterns = [
 | 
					    urlpatterns = [
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user