mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-07-23 22:49:50 +03:00
Merge b572ede48e
into 628e3bf001
This commit is contained in:
commit
368b769977
|
@ -213,3 +213,23 @@ class RetrieveUpdateDestroyAPIView(mixins.RetrieveModelMixin,
|
|||
|
||||
def delete(self, request, *args, **kwargs):
|
||||
return self.destroy(request, *args, **kwargs)
|
||||
|
||||
class RedirectAPIView(mixins.RedirectMixin,
|
||||
GenericAPIView):
|
||||
"""
|
||||
Redirect View used to redirect requests to a different/moved endpoint
|
||||
"""
|
||||
def get(self, request, *args, **kwargs):
|
||||
return self.redirect(request, *args, **kwargs)
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
return self.redirect(request, *args, **kwargs)
|
||||
|
||||
def options(self, request, *args, **kwargs):
|
||||
return self.redirect(request, *args, **kwargs)
|
||||
|
||||
def delete(self, request, *args, **kwargs):
|
||||
return self.redirect(request, *args, **kwargs)
|
||||
|
||||
def put(self, request, *args, **kwargs):
|
||||
return self.redirect(request, *args, **kwargs)
|
|
@ -7,6 +7,7 @@ which allows mixin classes to be composed in interesting ways.
|
|||
from django.http import Http404
|
||||
from rest_framework import status
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.reverse import reverse
|
||||
|
||||
|
||||
class CreateModelMixin(object):
|
||||
|
@ -123,3 +124,42 @@ class DestroyModelMixin(object):
|
|||
self.object = self.get_object()
|
||||
self.object.delete()
|
||||
return Response(status=status.HTTP_204_NO_CONTENT)
|
||||
|
||||
class RedirectMixin(object):
|
||||
"""
|
||||
A Mixin that provides a redirect method,
|
||||
redirecting to a different resource endpoint
|
||||
"""
|
||||
redirect_permanent = True
|
||||
redirect_with_query_string = True
|
||||
redirect_to_view_name = None
|
||||
redirect_to_url = None
|
||||
|
||||
def get_redirect_url(self, request, *args, **kwargs):
|
||||
"""
|
||||
Returning where to redirect to.
|
||||
To url, view-name or nowhere
|
||||
"""
|
||||
if self.redirect_to_url:
|
||||
url = self.redirect_to_url % kwargs
|
||||
else:
|
||||
try:
|
||||
url = reverse(self.redirect_view_name, args=args, kwargs=kwargs, request=request)
|
||||
except:
|
||||
return None
|
||||
|
||||
query_string = self.request.META.get('QUERY_STRING', '')
|
||||
if query_string and self.redirect_with_query_string:
|
||||
url = '%(url)s?%(query_string)s' % {'url': url, 'query_string': query_string}
|
||||
return url
|
||||
|
||||
def redirect(self, request, *args, **kwargs):
|
||||
url = self.get_redirect_url(request, *args, **kwargs)
|
||||
if url:
|
||||
headers = {'Location': url}
|
||||
if self.redirect_permanent:
|
||||
return Response(status=status.HTTP_301_MOVED_PERMANENTLY, headers=headers)
|
||||
else:
|
||||
return Response(status=status.HTTP_302_FOUND, headers=headers)
|
||||
else:
|
||||
return Response(status=status.HTTP_410_GONE)
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
from django.test import TestCase
|
||||
from django.conf.urls.defaults import patterns, url
|
||||
from django.test.client import RequestFactory
|
||||
from django.utils import simplejson as json
|
||||
from rest_framework import generics, serializers, status
|
||||
|
@ -14,13 +15,19 @@ class RootView(generics.ListCreateAPIView):
|
|||
"""
|
||||
model = BasicModel
|
||||
|
||||
|
||||
class InstanceView(generics.RetrieveUpdateDestroyAPIView):
|
||||
"""
|
||||
Example description for OPTIONS.
|
||||
"""
|
||||
model = BasicModel
|
||||
|
||||
class RedirectToRootView(generics.RedirectAPIView):
|
||||
redirect_permanent = False
|
||||
redirect_view_name = 'root-view'
|
||||
|
||||
class RedirectToURL(generics.RedirectAPIView):
|
||||
redirect_to_url = 'http://foo.bar'
|
||||
redirect_with_query_string = False
|
||||
|
||||
class SlugSerializer(serializers.ModelSerializer):
|
||||
slug = serializers.Field() # read only
|
||||
|
@ -38,6 +45,10 @@ class SlugBasedInstanceView(InstanceView):
|
|||
serializer_class = SlugSerializer
|
||||
|
||||
|
||||
urlpatterns = patterns('',
|
||||
url(r'^root/$', RootView.as_view(), name='root-view'),
|
||||
)
|
||||
|
||||
class TestRootView(TestCase):
|
||||
def setUp(self):
|
||||
"""
|
||||
|
@ -301,3 +312,28 @@ class TestCreateModelWithAutoNowAddField(TestCase):
|
|||
self.assertEquals(response.status_code, status.HTTP_201_CREATED)
|
||||
created = self.objects.get(id=1)
|
||||
self.assertEquals(created.content, 'foobar')
|
||||
|
||||
class RedirectViewTests(TestCase):
|
||||
urls = 'rest_framework.tests.generics'
|
||||
|
||||
def test_redirect(self):
|
||||
request = factory.get('/redirect_to_root/?foo=bar')
|
||||
response = RedirectToRootView.as_view()(request)
|
||||
|
||||
self.assertEquals(response.status_code, status.HTTP_302_FOUND)
|
||||
self.assertEquals(response['Location'], 'http://testserver/root/?foo=bar')
|
||||
|
||||
def test_redirect_to_nowhere(self):
|
||||
request = factory.get('/redirect_to_nowhere/')
|
||||
response = generics.RedirectAPIView.as_view()(request)
|
||||
|
||||
self.assertEquals(response.status_code, status.HTTP_410_GONE)
|
||||
|
||||
def test_redirect_to_url(self):
|
||||
request = factory.get('/redirect_to_url/?foo=bar')
|
||||
response = RedirectToURL.as_view()(request)
|
||||
|
||||
self.assertEquals(response.status_code, status.HTTP_301_MOVED_PERMANENTLY)
|
||||
self.assertEquals(response['Location'], 'http://foo.bar')
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user