mirror of
				https://github.com/encode/django-rest-framework.git
				synced 2025-11-04 18:08:03 +03:00 
			
		
		
		
	Merge with 4b1ee62051cce8fa9b83ac740d7262ad4a55494b
This commit is contained in:
		
						commit
						209ee82903
					
				| 
						 | 
					@ -67,6 +67,14 @@ except ImportError:
 | 
				
			||||||
# django.views.generic.View (Django >= 1.3)
 | 
					# django.views.generic.View (Django >= 1.3)
 | 
				
			||||||
try:
 | 
					try:
 | 
				
			||||||
    from django.views.generic import View
 | 
					    from django.views.generic import View
 | 
				
			||||||
 | 
					    if not hasattr(View, 'head'):
 | 
				
			||||||
 | 
					        # First implementation of Django class-based views did not include head method 
 | 
				
			||||||
 | 
					        # in base View class - https://code.djangoproject.com/ticket/15668
 | 
				
			||||||
 | 
					        class ViewPlusHead(View):
 | 
				
			||||||
 | 
					            def head(self, request, *args, **kwargs):
 | 
				
			||||||
 | 
					                return self.get(request, *args, **kwargs)
 | 
				
			||||||
 | 
					        View = ViewPlusHead
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
except ImportError:
 | 
					except ImportError:
 | 
				
			||||||
    from django import http
 | 
					    from django import http
 | 
				
			||||||
    from django.utils.functional import update_wrapper
 | 
					    from django.utils.functional import update_wrapper
 | 
				
			||||||
| 
						 | 
					@ -145,6 +153,8 @@ except ImportError:
 | 
				
			||||||
            #)
 | 
					            #)
 | 
				
			||||||
            return http.HttpResponseNotAllowed(allowed_methods)
 | 
					            return http.HttpResponseNotAllowed(allowed_methods)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        def head(self, request, *args, **kwargs):
 | 
				
			||||||
 | 
					            return self.get(request, *args, **kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
try:
 | 
					try:
 | 
				
			||||||
    import markdown
 | 
					    import markdown
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -17,6 +17,7 @@ from djangorestframework.utils import dict2xml, url_resolves
 | 
				
			||||||
from djangorestframework.utils.breadcrumbs import get_breadcrumbs
 | 
					from djangorestframework.utils.breadcrumbs import get_breadcrumbs
 | 
				
			||||||
from djangorestframework.utils.description import get_name, get_description
 | 
					from djangorestframework.utils.description import get_name, get_description
 | 
				
			||||||
from djangorestframework.utils.mediatypes import get_media_type_params, add_media_type_param, media_type_matches
 | 
					from djangorestframework.utils.mediatypes import get_media_type_params, add_media_type_param, media_type_matches
 | 
				
			||||||
 | 
					from djangorestframework import VERSION
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from decimal import Decimal
 | 
					from decimal import Decimal
 | 
				
			||||||
import re
 | 
					import re
 | 
				
			||||||
| 
						 | 
					@ -285,6 +286,7 @@ class DocumentingTemplateRenderer(BaseRenderer):
 | 
				
			||||||
            'response': self.view.response,
 | 
					            'response': self.view.response,
 | 
				
			||||||
            'description': description,
 | 
					            'description': description,
 | 
				
			||||||
            'name': name,
 | 
					            'name': name,
 | 
				
			||||||
 | 
					            'version': VERSION,
 | 
				
			||||||
            'markeddown': markeddown,
 | 
					            'markeddown': markeddown,
 | 
				
			||||||
            'breadcrumblist': breadcrumb_list,
 | 
					            'breadcrumblist': breadcrumb_list,
 | 
				
			||||||
            'available_media_types': self.view._rendered_media_types,
 | 
					            'available_media_types': self.view._rendered_media_types,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,7 +6,7 @@ from django.db.models.fields.related import RelatedField
 | 
				
			||||||
from django.utils.encoding import smart_unicode
 | 
					from django.utils.encoding import smart_unicode
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from djangorestframework.response import ErrorResponse
 | 
					from djangorestframework.response import ErrorResponse
 | 
				
			||||||
from djangorestframework.serializer import Serializer
 | 
					from djangorestframework.serializer import Serializer, _SkipField
 | 
				
			||||||
from djangorestframework.utils import as_tuple
 | 
					from djangorestframework.utils import as_tuple
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import decimal
 | 
					import decimal
 | 
				
			||||||
| 
						 | 
					@ -342,7 +342,7 @@ class ModelResource(FormResource):
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if not hasattr(self, 'view_callable'):
 | 
					        if not hasattr(self, 'view_callable'):
 | 
				
			||||||
            raise NoReverseMatch        
 | 
					            raise _SkipField        
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # dis does teh magicks...
 | 
					        # dis does teh magicks...
 | 
				
			||||||
        urlconf = get_urlconf()
 | 
					        urlconf = get_urlconf()
 | 
				
			||||||
| 
						 | 
					@ -371,7 +371,7 @@ class ModelResource(FormResource):
 | 
				
			||||||
                    return reverse(self.view_callable[0], kwargs=instance_attrs)
 | 
					                    return reverse(self.view_callable[0], kwargs=instance_attrs)
 | 
				
			||||||
                except NoReverseMatch:
 | 
					                except NoReverseMatch:
 | 
				
			||||||
                    pass
 | 
					                    pass
 | 
				
			||||||
        raise NoReverseMatch
 | 
					        raise _SkipField
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @property
 | 
					    @property
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -16,13 +16,13 @@ class Response(object):
 | 
				
			||||||
    An HttpResponse that may include content that hasn't yet been serialized.
 | 
					    An HttpResponse that may include content that hasn't yet been serialized.
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, status=200, content=None, headers={}):
 | 
					    def __init__(self, status=200, content=None, headers=None):
 | 
				
			||||||
        self.status = status
 | 
					        self.status = status
 | 
				
			||||||
        self.media_type = None
 | 
					        self.media_type = None
 | 
				
			||||||
        self.has_content_body = content is not None
 | 
					        self.has_content_body = content is not None
 | 
				
			||||||
        self.raw_content = content      # content prior to filtering
 | 
					        self.raw_content = content      # content prior to filtering
 | 
				
			||||||
        self.cleaned_content = content  # content after filtering
 | 
					        self.cleaned_content = content  # content after filtering
 | 
				
			||||||
        self.headers = headers
 | 
					        self.headers = headers or {}
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
    @property
 | 
					    @property
 | 
				
			||||||
    def status_text(self):
 | 
					    def status_text(self):
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -18,7 +18,7 @@
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
	<div id="header">
 | 
						<div id="header">
 | 
				
			||||||
		<div id="branding">
 | 
							<div id="branding">
 | 
				
			||||||
		  <h1 id="site-name"><a href='http://django-rest-framework.org'>Django REST framework</a></h1>
 | 
							  <h1 id="site-name"><a href='http://django-rest-framework.org'>Django REST framework</a> <small>{{ version }}</small></h1>
 | 
				
			||||||
		</div>
 | 
							</div>
 | 
				
			||||||
		<div id="user-tools">
 | 
							<div id="user-tools">
 | 
				
			||||||
		  {% if user.is_active %}Welcome, {{ user }}.{% if logout_url %} <a href='{{ logout_url }}'>Log out</a>{% endif %}{% else %}Anonymous {% if login_url %}<a href='{{ login_url }}'>Log in</a>{% endif %}{% endif %}
 | 
							  {% if user.is_active %}Welcome, {{ user }}.{% if logout_url %} <a href='{{ logout_url }}'>Log out</a>{% endif %}{% else %}Anonymous {% if login_url %}<a href='{{ login_url }}'>Log in</a>{% endif %}{% endif %}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,7 +6,6 @@ from djangorestframework.compat import RequestFactory
 | 
				
			||||||
from djangorestframework.mixins import RequestMixin
 | 
					from djangorestframework.mixins import RequestMixin
 | 
				
			||||||
from djangorestframework.parsers import FormParser, MultiPartParser, PlainTextParser
 | 
					from djangorestframework.parsers import FormParser, MultiPartParser, PlainTextParser
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
class TestContentParsing(TestCase):
 | 
					class TestContentParsing(TestCase):
 | 
				
			||||||
    def setUp(self):
 | 
					    def setUp(self):
 | 
				
			||||||
        self.req = RequestFactory()
 | 
					        self.req = RequestFactory()
 | 
				
			||||||
| 
						 | 
					@ -16,6 +15,11 @@ class TestContentParsing(TestCase):
 | 
				
			||||||
        view.request = self.req.get('/')
 | 
					        view.request = self.req.get('/')
 | 
				
			||||||
        self.assertEqual(view.DATA, None)
 | 
					        self.assertEqual(view.DATA, None)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def ensure_determines_no_content_HEAD(self, view):
 | 
				
			||||||
 | 
					        """Ensure view.DATA returns None for HEAD request."""
 | 
				
			||||||
 | 
					        view.request = self.req.head('/')
 | 
				
			||||||
 | 
					        self.assertEqual(view.DATA, None)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def ensure_determines_form_content_POST(self, view):
 | 
					    def ensure_determines_form_content_POST(self, view):
 | 
				
			||||||
        """Ensure view.DATA returns content for POST request with form content."""
 | 
					        """Ensure view.DATA returns content for POST request with form content."""
 | 
				
			||||||
        form_data = {'qwerty': 'uiop'}
 | 
					        form_data = {'qwerty': 'uiop'}
 | 
				
			||||||
| 
						 | 
					@ -50,6 +54,10 @@ class TestContentParsing(TestCase):
 | 
				
			||||||
        """Ensure view.DATA returns None for GET request with no content."""
 | 
					        """Ensure view.DATA returns None for GET request with no content."""
 | 
				
			||||||
        self.ensure_determines_no_content_GET(RequestMixin())
 | 
					        self.ensure_determines_no_content_GET(RequestMixin())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_standard_behaviour_determines_no_content_HEAD(self):
 | 
				
			||||||
 | 
					        """Ensure view.DATA returns None for HEAD request."""
 | 
				
			||||||
 | 
					        self.ensure_determines_no_content_HEAD(RequestMixin())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_standard_behaviour_determines_form_content_POST(self):
 | 
					    def test_standard_behaviour_determines_form_content_POST(self):
 | 
				
			||||||
        """Ensure view.DATA returns content for POST request with form content."""
 | 
					        """Ensure view.DATA returns content for POST request with form content."""
 | 
				
			||||||
        self.ensure_determines_form_content_POST(RequestMixin())
 | 
					        self.ensure_determines_form_content_POST(RequestMixin())
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -24,3 +24,9 @@ class TestMethodOverloading(TestCase):
 | 
				
			||||||
        view = RequestMixin()
 | 
					        view = RequestMixin()
 | 
				
			||||||
        view.request = self.req.post('/', {view._METHOD_PARAM: 'DELETE'})
 | 
					        view.request = self.req.post('/', {view._METHOD_PARAM: 'DELETE'})
 | 
				
			||||||
        self.assertEqual(view.method, 'DELETE')
 | 
					        self.assertEqual(view.method, 'DELETE')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_HEAD_is_a_valid_method(self):
 | 
				
			||||||
 | 
					        """HEAD requests identified"""
 | 
				
			||||||
 | 
					        view = RequestMixin()
 | 
				
			||||||
 | 
					        view.request = self.req.head('/')
 | 
				
			||||||
 | 
					        self.assertEqual(view.method, 'HEAD')
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -55,6 +55,13 @@ class RendererIntegrationTests(TestCase):
 | 
				
			||||||
        self.assertEquals(resp.content, RENDERER_A_SERIALIZER(DUMMYCONTENT))
 | 
					        self.assertEquals(resp.content, RENDERER_A_SERIALIZER(DUMMYCONTENT))
 | 
				
			||||||
        self.assertEquals(resp.status_code, DUMMYSTATUS)
 | 
					        self.assertEquals(resp.status_code, DUMMYSTATUS)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_head_method_serializes_no_content(self):
 | 
				
			||||||
 | 
					        """No response must be included in HEAD requests."""
 | 
				
			||||||
 | 
					        resp = self.client.head('/')
 | 
				
			||||||
 | 
					        self.assertEquals(resp.status_code, DUMMYSTATUS)
 | 
				
			||||||
 | 
					        self.assertEquals(resp['Content-Type'], RendererA.media_type)
 | 
				
			||||||
 | 
					        self.assertEquals(resp.content, '')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_default_renderer_serializes_content_on_accept_any(self):
 | 
					    def test_default_renderer_serializes_content_on_accept_any(self):
 | 
				
			||||||
        """If the Accept header is set to */* the default renderer should serialize the response."""
 | 
					        """If the Accept header is set to */* the default renderer should serialize the response."""
 | 
				
			||||||
        resp = self.client.get('/', HTTP_ACCEPT='*/*')
 | 
					        resp = self.client.get('/', HTTP_ACCEPT='*/*')
 | 
				
			||||||
| 
						 | 
					@ -83,8 +90,6 @@ class RendererIntegrationTests(TestCase):
 | 
				
			||||||
        resp = self.client.get('/', HTTP_ACCEPT='foo/bar')
 | 
					        resp = self.client.get('/', HTTP_ACCEPT='foo/bar')
 | 
				
			||||||
        self.assertEquals(resp.status_code, 406)
 | 
					        self.assertEquals(resp.status_code, 406)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
_flat_repr = '{"foo": ["bar", "baz"]}'
 | 
					_flat_repr = '{"foo": ["bar", "baz"]}'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
_indented_repr = """{
 | 
					_indented_repr = """{
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user