Skip to content

Commit

Permalink
Added API with no DRf chapter
Browse files Browse the repository at this point in the history
  • Loading branch information
shabda committed Mar 12, 2018
1 parent e1fac97 commit 53cabcf
Show file tree
Hide file tree
Showing 9 changed files with 121 additions and 9 deletions.
86 changes: 86 additions & 0 deletions docs/apis-without-drf.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
A simple API with pure Django
========================================

In this chapter, we will build an API with urse Django. We will not use Django Rest Framework (Or any other library).

The endpoints and the URLS
+++++++++++++++++++++++++++++++

Our API will have two engpoints returning data in JSON format.

* :code:`/polls/` GETs list of :code:`Poll`
* GET :code:`/polls/{id}/` GETs data of a specific :code:`Poll`

Connecting urls to the views
++++++++++++++++++++++++++++++

Write two place holder view functions and connect them in your :code:`urls.py`. We will finish :code:`polls_list` and :code:`polls_detail` shortly.

.. code-block:: python
# In views.py
def polls_list(request):
pass
def polls_detail(request, pk):
pass
# in urls.py
...
from .views import polls_list, polls_detail
urlpatterns = [
path("polls/", polls_list, name="polls_list"),
path("polls/<int:pk>/", polls_detail, name="polls_detail")
]
Writing the views
++++++++++++++++++++++++

We will now write the :code:`polls_list` and :code:`polls_detail`

.. code-block:: python
from django.shortcuts import render, get_object_or_404
from django.http import JsonResponse
from .models import Poll
def polls_list(request):
MAX_OBJECTS = 20
polls = Poll.objects.all()[:20]
data = {"results": list(polls.values("question", "created_by__username", "pub_date"))}
return JsonResponse(data)
def polls_detail(request, pk):
poll = get_object_or_404(Poll, pk=pk)
data = {"results": {
"question": poll.question,
"created_by": poll.created_by.username,
"pub_date": poll.pub_date
}}
return JsonResponse(data)
This should be standard Django for you. :code:`polls = Poll.objects.all()[:20]` gets us upto 20 :code:`Poll` objects.
We get a list of dictionaries using `{"results": list(polls.values("question", "created_by__username", "pub_date"))}` and return it with a :code:`JsonResponse`. A :code:`JsonResponse` is a like :code:`HttpResponse` with :code:`content-type=application/json`.

Similarly, `polls_detail` gets a specific Poll using :code:`get_object_or_404(Poll, pk=pk)`, and returns it wrapped in :code:`JsonResponse`.


Using the API
++++++++++++++++++++++++

You can now access the API using curl, wget, postman, browser or any other API consuming tools. Here us the response with curl.

.. code-block:: bash
$ curl http://localhost:8000/polls/
{"results": [{"pk": 1, "question": "What is the weight of an unladen swallow?", "created_by__username": "shabda", "pub_date": "2018-03-12T10:14:19.002Z"}, {"pk": 2, "question": "What do you prefer, Flask or Django?", "created_by__username": "shabda", "pub_date": "2018-03-12T10:15:55.949Z"}, {"pk": 3, "question": "What is your favorite vacation spot?", "created_by__username": "shabda", "pub_date": "2018-03-12T10:16:11.998Z"}]}
You should consider using postman or a similar tool. He is how your API looks in Postman.

.. image:: postman_polls_detail.png
8 changes: 4 additions & 4 deletions docs/chapter1.rst
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Setup, Models and Admin
=============================

In this tutorial we will walk through a process of creating an API for a basic poll application. We will be using python 3.6.x, Django 2.0.x and Django Rest Framework 3.7.7 for creating API.
In this tutorial we will walk through a process of creating an API for a basic poll application. We will be using Python 3.6.x, Django 2.0.x and Django Rest Framework 3.7.x for creating API.

First things first, let's install the required modules within a virtual environment.

Expand All @@ -14,7 +14,7 @@ First things first, let's install the required modules within a virtual environm
Creating a project
--------------------

Earliest in order, to create a project we should move to the directory where we would like to store our code. For this go to command line and use cd command. Then trigger the start prject command.
Earliest in order, to create a project we should move to the directory where we would like to store our code. For this go to command line and use cd command. Then trigger the startproject command.

.. code-block:: python
Expand Down Expand Up @@ -82,15 +82,15 @@ These models are the same as you would have seen in the Django introduction tuto
created_by = models.ForeignKey(User, on_delete=models.CASCADE)
pub_date = models.DateTimeField(auto_now=True)
def __unicode__(self):
def __str__(self):
return self.question
class Choice(models.Model):
poll = models.ForeignKey(Poll, related_name='choices',on_delete=models.CASCADE)
choice_text = models.CharField(max_length=100)
def __unicode__(self):
def __str__(self):
return self.choice_text
Expand Down
1 change: 1 addition & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ Contents:
:maxdepth: 2

chapter1
apis-without-drf
chapter2
chapter3
chapter4
Expand Down
Binary file added docs/postman_polls_detail.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed pollsapi/db.sqlite3
Binary file not shown.
4 changes: 3 additions & 1 deletion pollsapi/polls/admin.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from django.contrib import admin

# Register your models here.
from .models import Poll

admin.site.register(Poll)
4 changes: 2 additions & 2 deletions pollsapi/polls/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@ class Poll(models.Model):
created_by = models.ForeignKey(User, on_delete=models.CASCADE)
pub_date = models.DateTimeField(auto_now=True)

def __unicode__(self):
def __str__(self):
return self.question


class Choice(models.Model):
poll = models.ForeignKey(Poll, related_name='choices',on_delete=models.CASCADE)
choice_text = models.CharField(max_length=100)

def __unicode__(self):
def __str__(self):
return self.choice_text


Expand Down
6 changes: 6 additions & 0 deletions pollsapi/polls/urls.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,8 @@
from django.urls import path

from .views import polls_list, polls_detail

urlpatterns = [
path("polls/", polls_list, name="polls_list"),
path("polls/<int:pk>/", polls_detail, name="polls_detail")
]
21 changes: 19 additions & 2 deletions pollsapi/polls/views.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,20 @@
from django.shortcuts import render
from django.shortcuts import render, get_object_or_404
from django.http import JsonResponse

# Create your views here.
from .models import Poll

def polls_list(request):
MAX_OBJECTS = 20
polls = Poll.objects.all()[:20]
data = {"results": list(polls.values("pk", "question", "created_by__username", "pub_date"))}
return JsonResponse(data)


def polls_detail(request, pk):
poll = get_object_or_404(Poll, pk=pk)
data = {"results": {
"question": poll.question,
"created_by": poll.created_by.username,
"pub_date": poll.pub_date
}}
return JsonResponse(data)

0 comments on commit 53cabcf

Please sign in to comment.