From 7310f1818c876a0883c9484a5ca2be4af819ca70 Mon Sep 17 00:00:00 2001 From: JasonHomeWorkstationUbuntu Date: Wed, 21 Oct 2020 15:35:55 +1100 Subject: [PATCH] urls.py and views.py are setup for browsable API --- README.md | 12 +++++++++ puppy_store/puppies/tests/test_views.py | 10 ++++++++ puppy_store/puppies/urls.py | 16 ++++++++++++ puppy_store/puppies/views.py | 33 ++++++++++++++++++++++++- puppy_store/puppy_store/settings.py | 12 ++++----- puppy_store/puppy_store/urls.py | 6 +++++ 6 files changed, 82 insertions(+), 7 deletions(-) create mode 100644 puppy_store/puppies/tests/test_views.py create mode 100644 puppy_store/puppies/urls.py diff --git a/README.md b/README.md index c453ece..3892be0 100644 --- a/README.md +++ b/README.md @@ -2,3 +2,15 @@ This is a practice repository following [Test Driven Development of a Django RESTful API](https://realpython.com/test-driven-development-of-a-django-restful-api/) +## RESTful Structure + +In a RESTful API, endpoints (URLs) define the structure of the API and how end users access data from our application using the HTTP methods - GET, POST, PUT, DELETE. Endpoints should be logically organized around collections and elements, both of which are resources. + +In our case, we have one single resource, puppies, so we will use the following URLS - /puppies/ and /puppies/ for collections and elements, respectively + +## Routes and TDD + +Process for development: +1. Create skeleton code that doomed to fail +2. Add a unit test for failure +3. Update the code to make it pass the test. \ No newline at end of file diff --git a/puppy_store/puppies/tests/test_views.py b/puppy_store/puppies/tests/test_views.py new file mode 100644 index 0000000..299c5aa --- /dev/null +++ b/puppy_store/puppies/tests/test_views.py @@ -0,0 +1,10 @@ +import json +from rest_framework import status +from django.test import TestCase, Client +from django.urls import reverse + +from ..models import Puppy +from ..serializers import PuppySerializer + +# initialize the APIClient app +client = Client() \ No newline at end of file diff --git a/puppy_store/puppies/urls.py b/puppy_store/puppies/urls.py new file mode 100644 index 0000000..b4663aa --- /dev/null +++ b/puppy_store/puppies/urls.py @@ -0,0 +1,16 @@ +from django.conf.urls import url +from . import views + +urlpatterns = [ + # suppose this is the django1's code style, check django REST framework for django3.1 + url( + r'^api/v1/puppies/(?P[0-9]+)$', + views.get_delete_update_puppy, + name='get_delete_update_puppy' + ), + url( + r'^api/v1/puppies/$', + views.get_post_puppies, + name='get_post_puppies' + ) +] \ No newline at end of file diff --git a/puppy_store/puppies/views.py b/puppy_store/puppies/views.py index 91ea44a..870451a 100644 --- a/puppy_store/puppies/views.py +++ b/puppy_store/puppies/views.py @@ -1,3 +1,34 @@ from django.shortcuts import render +from django.test.client import RequestFactory +from rest_framework.decorators import api_view +from rest_framework.response import Response +from rest_framework import status -# Create your views here. +from .models import Puppy +from .serializers import PuppySerializer + +@api_view(['GET', 'DELETE', 'PUT']) +def get_delete_update_puppy(request, pk): + try: + puppy = Puppy.objects.get(pk=pk) + except Puppy.DoesNotExist: + return Response(status=status.HTTP_404_NOT_FOUND) + + # get details of a single puppy + if request.method == 'GET': + return Response({}) + # delete a single puppy + elif request.method == 'DELETE': + return Response({}) + # update details of a single puppy + elif request.method == 'PUT': + return Response({}) + +@api_view(['GET', 'POST']) +def get_post_puppies(request): + # get all puppies + if request.method == 'GET': + return Response({}) + # insert a new record for a puppy + elif request.method == 'POST': + return Response({}) \ No newline at end of file diff --git a/puppy_store/puppy_store/settings.py b/puppy_store/puppy_store/settings.py index f661ad6..821c9cf 100644 --- a/puppy_store/puppy_store/settings.py +++ b/puppy_store/puppy_store/settings.py @@ -123,9 +123,9 @@ USE_TZ = True STATIC_URL = '/static/' -REST_FRAMEWORK = { - # Use Django's standard `django.contrib.auth` permission - # or allow read-only access for unauthenticated users. - 'DEFAULT_PERMISSION_CLASSES': [], - 'TEST_REQUEST_DEFAULT_FORMAT': 'json' -} \ No newline at end of file +# REST_FRAMEWORK = { +# # Use Django's standard `django.contrib.auth` permission +# # or allow read-only access for unauthenticated users. +# 'DEFAULT_PERMISSION_CLASSES': [], +# 'TEST_REQUEST_DEFAULT_FORMAT': 'json' +# } \ No newline at end of file diff --git a/puppy_store/puppy_store/urls.py b/puppy_store/puppy_store/urls.py index 9de1c60..e0c404c 100644 --- a/puppy_store/puppy_store/urls.py +++ b/puppy_store/puppy_store/urls.py @@ -15,7 +15,13 @@ Including another URLconf """ from django.contrib import admin from django.urls import path +from django.conf.urls import include, url # for django 1.x urlpatterns = [ + url(r'^', include('puppies.urls')), + url( + r'^api-auth/', + include('rest_framework.urls', namespace='rest_framework') + ), path('admin/', admin.site.urls), ]