aboutsummaryrefslogtreecommitdiffstats
path: root/djangorestframework
diff options
context:
space:
mode:
authormarkotibold2011-06-25 17:31:04 +0200
committermarkotibold2011-06-25 17:31:04 +0200
commit209ee829031ff69ddfe275ee0e41c173f5dec2f4 (patch)
treefc347393d7567217cef459fbf863c2ad6962d414 /djangorestframework
parentbae21b14c93e458014107a007e894e93a181bd0e (diff)
parentd3024ff18150e41190da76592d948b724727ca74 (diff)
downloaddjango-rest-framework-209ee829031ff69ddfe275ee0e41c173f5dec2f4.tar.bz2
Merge with 4b1ee62051cce8fa9b83ac740d7262ad4a55494b
Diffstat (limited to 'djangorestframework')
-rw-r--r--djangorestframework/compat.py12
-rw-r--r--djangorestframework/renderers.py2
-rw-r--r--djangorestframework/resources.py6
-rw-r--r--djangorestframework/response.py4
-rw-r--r--djangorestframework/templates/renderer.html2
-rw-r--r--djangorestframework/tests/content.py10
-rw-r--r--djangorestframework/tests/methods.py6
-rw-r--r--djangorestframework/tests/renderers.py9
8 files changed, 41 insertions, 10 deletions
diff --git a/djangorestframework/compat.py b/djangorestframework/compat.py
index 0274511a..827b4adf 100644
--- a/djangorestframework/compat.py
+++ b/djangorestframework/compat.py
@@ -67,6 +67,14 @@ except ImportError:
# django.views.generic.View (Django >= 1.3)
try:
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:
from django import http
from django.utils.functional import update_wrapper
@@ -145,6 +153,8 @@ except ImportError:
#)
return http.HttpResponseNotAllowed(allowed_methods)
+ def head(self, request, *args, **kwargs):
+ return self.get(request, *args, **kwargs)
try:
import markdown
@@ -193,4 +203,4 @@ try:
return md.convert(text)
except ImportError:
- apply_markdown = None \ No newline at end of file
+ apply_markdown = None
diff --git a/djangorestframework/renderers.py b/djangorestframework/renderers.py
index 56939bbc..13cd52f5 100644
--- a/djangorestframework/renderers.py
+++ b/djangorestframework/renderers.py
@@ -17,6 +17,7 @@ from djangorestframework.utils import dict2xml, url_resolves
from djangorestframework.utils.breadcrumbs import get_breadcrumbs
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 import VERSION
from decimal import Decimal
import re
@@ -285,6 +286,7 @@ class DocumentingTemplateRenderer(BaseRenderer):
'response': self.view.response,
'description': description,
'name': name,
+ 'version': VERSION,
'markeddown': markeddown,
'breadcrumblist': breadcrumb_list,
'available_media_types': self.view._rendered_media_types,
diff --git a/djangorestframework/resources.py b/djangorestframework/resources.py
index 08f9e0ae..b42bd952 100644
--- a/djangorestframework/resources.py
+++ b/djangorestframework/resources.py
@@ -6,7 +6,7 @@ from django.db.models.fields.related import RelatedField
from django.utils.encoding import smart_unicode
from djangorestframework.response import ErrorResponse
-from djangorestframework.serializer import Serializer
+from djangorestframework.serializer import Serializer, _SkipField
from djangorestframework.utils import as_tuple
import decimal
@@ -342,7 +342,7 @@ class ModelResource(FormResource):
"""
if not hasattr(self, 'view_callable'):
- raise NoReverseMatch
+ raise _SkipField
# dis does teh magicks...
urlconf = get_urlconf()
@@ -371,7 +371,7 @@ class ModelResource(FormResource):
return reverse(self.view_callable[0], kwargs=instance_attrs)
except NoReverseMatch:
pass
- raise NoReverseMatch
+ raise _SkipField
@property
diff --git a/djangorestframework/response.py b/djangorestframework/response.py
index d68ececf..311e0bb7 100644
--- a/djangorestframework/response.py
+++ b/djangorestframework/response.py
@@ -16,13 +16,13 @@ class Response(object):
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.media_type = None
self.has_content_body = content is not None
self.raw_content = content # content prior to filtering
self.cleaned_content = content # content after filtering
- self.headers = headers
+ self.headers = headers or {}
@property
def status_text(self):
diff --git a/djangorestframework/templates/renderer.html b/djangorestframework/templates/renderer.html
index 94748d28..97d3837a 100644
--- a/djangorestframework/templates/renderer.html
+++ b/djangorestframework/templates/renderer.html
@@ -18,7 +18,7 @@
<div id="header">
<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 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 %}
diff --git a/djangorestframework/tests/content.py b/djangorestframework/tests/content.py
index ee3597a4..83ad72d0 100644
--- a/djangorestframework/tests/content.py
+++ b/djangorestframework/tests/content.py
@@ -6,7 +6,6 @@ from djangorestframework.compat import RequestFactory
from djangorestframework.mixins import RequestMixin
from djangorestframework.parsers import FormParser, MultiPartParser, PlainTextParser
-
class TestContentParsing(TestCase):
def setUp(self):
self.req = RequestFactory()
@@ -16,6 +15,11 @@ class TestContentParsing(TestCase):
view.request = self.req.get('/')
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):
"""Ensure view.DATA returns content for POST request with form content."""
form_data = {'qwerty': 'uiop'}
@@ -50,6 +54,10 @@ class TestContentParsing(TestCase):
"""Ensure view.DATA returns None for GET request with no content."""
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):
"""Ensure view.DATA returns content for POST request with form content."""
self.ensure_determines_form_content_POST(RequestMixin())
diff --git a/djangorestframework/tests/methods.py b/djangorestframework/tests/methods.py
index d8f0d919..c3a3a28d 100644
--- a/djangorestframework/tests/methods.py
+++ b/djangorestframework/tests/methods.py
@@ -24,3 +24,9 @@ class TestMethodOverloading(TestCase):
view = RequestMixin()
view.request = self.req.post('/', {view._METHOD_PARAM: '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')
diff --git a/djangorestframework/tests/renderers.py b/djangorestframework/tests/renderers.py
index d403873f..569eb640 100644
--- a/djangorestframework/tests/renderers.py
+++ b/djangorestframework/tests/renderers.py
@@ -55,6 +55,13 @@ class RendererIntegrationTests(TestCase):
self.assertEquals(resp.content, RENDERER_A_SERIALIZER(DUMMYCONTENT))
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):
"""If the Accept header is set to */* the default renderer should serialize the response."""
resp = self.client.get('/', HTTP_ACCEPT='*/*')
@@ -83,8 +90,6 @@ class RendererIntegrationTests(TestCase):
resp = self.client.get('/', HTTP_ACCEPT='foo/bar')
self.assertEquals(resp.status_code, 406)
-
-
_flat_repr = '{"foo": ["bar", "baz"]}'
_indented_repr = """{