mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-07-24 23:19:47 +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):
|
def delete(self, request, *args, **kwargs):
|
||||||
return self.destroy(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 django.http import Http404
|
||||||
from rest_framework import status
|
from rest_framework import status
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
|
from rest_framework.reverse import reverse
|
||||||
|
|
||||||
|
|
||||||
class CreateModelMixin(object):
|
class CreateModelMixin(object):
|
||||||
|
@ -123,3 +124,42 @@ class DestroyModelMixin(object):
|
||||||
self.object = self.get_object()
|
self.object = self.get_object()
|
||||||
self.object.delete()
|
self.object.delete()
|
||||||
return Response(status=status.HTTP_204_NO_CONTENT)
|
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.test import TestCase
|
||||||
|
from django.conf.urls.defaults import patterns, url
|
||||||
from django.test.client import RequestFactory
|
from django.test.client import RequestFactory
|
||||||
from django.utils import simplejson as json
|
from django.utils import simplejson as json
|
||||||
from rest_framework import generics, serializers, status
|
from rest_framework import generics, serializers, status
|
||||||
|
@ -14,13 +15,19 @@ class RootView(generics.ListCreateAPIView):
|
||||||
"""
|
"""
|
||||||
model = BasicModel
|
model = BasicModel
|
||||||
|
|
||||||
|
|
||||||
class InstanceView(generics.RetrieveUpdateDestroyAPIView):
|
class InstanceView(generics.RetrieveUpdateDestroyAPIView):
|
||||||
"""
|
"""
|
||||||
Example description for OPTIONS.
|
Example description for OPTIONS.
|
||||||
"""
|
"""
|
||||||
model = BasicModel
|
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):
|
class SlugSerializer(serializers.ModelSerializer):
|
||||||
slug = serializers.Field() # read only
|
slug = serializers.Field() # read only
|
||||||
|
@ -38,6 +45,10 @@ class SlugBasedInstanceView(InstanceView):
|
||||||
serializer_class = SlugSerializer
|
serializer_class = SlugSerializer
|
||||||
|
|
||||||
|
|
||||||
|
urlpatterns = patterns('',
|
||||||
|
url(r'^root/$', RootView.as_view(), name='root-view'),
|
||||||
|
)
|
||||||
|
|
||||||
class TestRootView(TestCase):
|
class TestRootView(TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
"""
|
"""
|
||||||
|
@ -301,3 +312,28 @@ class TestCreateModelWithAutoNowAddField(TestCase):
|
||||||
self.assertEquals(response.status_code, status.HTTP_201_CREATED)
|
self.assertEquals(response.status_code, status.HTTP_201_CREATED)
|
||||||
created = self.objects.get(id=1)
|
created = self.objects.get(id=1)
|
||||||
self.assertEquals(created.content, 'foobar')
|
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