Browse Source

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

Better integration with DRF
David Leonard 9 years ago
parent
commit
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
 from hackathon import views
 
 
+router = DefaultRouter()
+router.register(r'snippets', views.SnippetView)
+
 urlpatterns = patterns('',
 urlpatterns = patterns('',
     url(r'^$', views.index, name='index'),
     url(r'^$', views.index, name='index'),
+    url(r'^', include(router.urls)),
     url(r'^register/$', views.register, name='register'),
     url(r'^register/$', views.register, name='register'),
     url(r'^login/$', views.user_login, name='login'),
     url(r'^login/$', views.user_login, name='login'),
     url(r'^logout/$', views.user_logout, name='logout'),
     url(r'^logout/$', views.user_logout, name='logout'),
@@ -15,7 +20,6 @@ urlpatterns = patterns('',
     url(r'^githubTopRepositories/$', views.githubTopRepositories, name='githubTopRepositories'),
     url(r'^githubTopRepositories/$', views.githubTopRepositories, name='githubTopRepositories'),
     url(r'^tumblr/$', views.tumblr, name='tumblr'),
     url(r'^tumblr/$', views.tumblr, name='tumblr'),
     url(r'^linkedin/$', views.linkedin, name='linkedin'),
     url(r'^linkedin/$', views.linkedin, name='linkedin'),
-    url(r'^snippets/$', views.snippet_list, name='snippets'),
     url(r'^twilio/$', views.twilio, name='twilio'),
     url(r'^twilio/$', views.twilio, name='twilio'),
     url(r'^instagram/$', views.instagram, name='instagram'),
     url(r'^instagram/$', views.instagram, name='instagram'),
     url(r'^instagram_login/$', views.instagram_login, name='instagram_login'),
     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.views.decorators.csrf import csrf_exempt
 from django.http import JsonResponse
 from django.http import JsonResponse
 
 
+# Django REST Framework
+from rest_framework import viewsets, mixins
+
 import requests
 import requests
 import pdb
 import pdb
 
 
@@ -35,8 +38,6 @@ from scripts.foursquare import *
 # Python
 # Python
 import oauth2 as oauth
 import oauth2 as oauth
 import simplejson as json
 import simplejson as json
-from rest_framework.renderers import JSONRenderer
-from rest_framework.parsers import JSONParser
 
 
 # Models
 # Models
 from hackathon.models import Snippet, Profile, InstagramProfile, TwitterProfile, MeetupToken, GithubProfile, LinkedinProfile, FacebookProfile, TumblrProfile, GoogleProfile, DropboxProfile, FoursquareProfile
 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 #
 # 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()
 
 
 
 
 ##################
 ##################