浏览代码

Merge pull request #25 from lwm/extended-rest-framework-snippet

Better integration with DRF
David Leonard 9 年之前
父节点
当前提交
69774d7ec6

+ 45 - 0
hackathon_starter/hackathon/unittests/testsnippets.py

@@ -0,0 +1,45 @@
+from hackathon.models import Snippet
+from rest_framework import status
+from rest_framework.test import APITestCase
+
+
+class SnippetViewTestCase(APITestCase):
+    def setUp(self):
+        self.s1 = Snippet.objects.create(title='t1', code="""print("Hello, World.")""")
+        self.s2 = Snippet.objects.create(title='t2', code="""print("Goodbye, World.")""")
+        super(SnippetViewTestCase, self).setUp()
+
+    def test_list(self):
+        response = self.client.get('/hackathon/snippets/')
+        self.assertEqual(response.status_code, status.HTTP_200_OK)
+        self.assertEqual(len(response.data), 2)
+
+    def test_detail(self):
+        response = self.client.get('/hackathon/snippets/{}/'.format(self.s1.id))
+        self.assertEqual(response.status_code, status.HTTP_200_OK)
+        self.assertEqual(response.data['id'], self.s1.id)
+
+    def test_create(self):
+        payload = {'title': 't3', 'code': """print("Create, World.")"""}
+        response = self.client.post('/hackathon/snippets/', payload)
+        self.assertEqual(response.status_code, status.HTTP_201_CREATED)
+        self.assertEqual(response.data['title'], 't3')
+        self.assertEqual(response.data['code'], """print("Create, World.")""")
+
+    def test_update(self):
+        payload = {'title': 't666', 'code': '2 + 2'}
+        response = self.client.put('/hackathon/snippets/{}/'.format(self.s1.id), payload)
+        self.assertEqual(response.status_code, status.HTTP_200_OK)
+        self.assertEqual(response.data['title'], 't666')
+        self.assertEqual(response.data['code'], '2 + 2')
+
+    def test_partial_update(self):
+        payload = {'title': 't666'}
+        response = self.client.patch('/hackathon/snippets/{}/'.format(self.s1.id), payload)
+        self.assertEqual(response.status_code, status.HTTP_200_OK)
+        self.assertEqual(response.data['title'], 't666')
+
+    def test_delete(self):
+        response = self.client.delete('/hackathon/snippets/{}/'.format(self.s1.id))
+        self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT)
+        self.assertEqual(Snippet.objects.count(), 1)

+ 6 - 2
hackathon_starter/hackathon/urls.py

@@ -1,9 +1,14 @@
-from django.conf.urls import patterns, url
+from django.conf.urls import patterns, url, include
+from rest_framework.routers import DefaultRouter
 
 from hackathon import views
 
+router = DefaultRouter()
+router.register(r'snippets', views.SnippetView)
+
 urlpatterns = patterns('',
     url(r'^$', views.index, name='index'),
+    url(r'^', include(router.urls)),
     url(r'^register/$', views.register, name='register'),
     url(r'^login/$', views.user_login, name='login'),
     url(r'^logout/$', views.user_logout, name='logout'),
@@ -15,7 +20,6 @@ urlpatterns = patterns('',
     url(r'^githubTopRepositories/$', views.githubTopRepositories, name='githubTopRepositories'),
     url(r'^tumblr/$', views.tumblr, name='tumblr'),
     url(r'^linkedin/$', views.linkedin, name='linkedin'),
-    url(r'^snippets/$', views.snippet_list, name='snippets'),
     url(r'^twilio/$', views.twilio, name='twilio'),
     url(r'^instagram/$', views.instagram, name='instagram'),
     url(r'^instagram_login/$', views.instagram_login, name='instagram_login'),

+ 14 - 20
hackathon_starter/hackathon/views.py

@@ -11,6 +11,9 @@ from django.contrib.auth.decorators import login_required
 from django.views.decorators.csrf import csrf_exempt
 from django.http import JsonResponse
 
+# Django REST Framework
+from rest_framework import viewsets, mixins
+
 import requests
 import pdb
 
@@ -35,8 +38,6 @@ from scripts.foursquare import *
 # Python
 import oauth2 as oauth
 import simplejson as json
-from rest_framework.renderers import JSONRenderer
-from rest_framework.parsers import JSONParser
 
 # Models
 from hackathon.models import Snippet, Profile, InstagramProfile, TwitterProfile, MeetupToken, GithubProfile, LinkedinProfile, FacebookProfile, TumblrProfile, GoogleProfile, DropboxProfile, FoursquareProfile
@@ -707,24 +708,17 @@ def linkedin(request):
 # Snippet RESTful Model #
 #########################
 
-class JSONResponse(HttpResponse):
-    """
-    An HttpResponse that renders its content into JSON.
-    """
-    def __init__(self, data, **kwargs):
-        content = JSONRenderer().render(data)
-        kwargs['content_type'] = 'application/json'
-        super(JSONResponse, self).__init__(content, **kwargs)
-
-@csrf_exempt
-def snippet_list(request):
-    """
-    List all code snippets, or create a new snippet.
-    """
-    if request.method == 'GET':
-        snippets = Snippet.objects.all()
-        serializer = SnippetSerializer(snippets, many=True)
-        return JSONResponse(serializer.data)
+class CRUDBaseView(mixins.ListModelMixin,
+                  mixins.CreateModelMixin,
+                  mixins.RetrieveModelMixin,
+                  mixins.UpdateModelMixin,
+                  mixins.DestroyModelMixin,
+                  viewsets.GenericViewSet):
+    pass
+
+class SnippetView(CRUDBaseView):
+    serializer_class = SnippetSerializer
+    queryset = Snippet.objects.all()
 
 
 ##################