Skip to content

Commit

Permalink
Merge branch 'master' of github.com:agiliq/building-api-django
Browse files Browse the repository at this point in the history
  • Loading branch information
shabda committed Mar 15, 2018
2 parents 700663c + c2fa3f8 commit 115aebf
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 19 deletions.
10 changes: 5 additions & 5 deletions docs/apis-without-drf.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ To start add some :code:`Poll` using the admin.
The endpoints and the URLS
+++++++++++++++++++++++++++++++

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

* :code:`/polls/` GETs list of :code:`Poll`
* GET :code:`/polls/<id>/` GETs data of a specific :code:`Poll`
* :code:`/polls/<id>/` GETs data of a specific :code:`Poll`

Connecting urls to the views
++++++++++++++++++++++++++++++
Expand All @@ -28,7 +28,7 @@ Write two place holder view functions and connect them in your :code:`urls.py`.
# in urls.py
...
from django.urls import path
from .views import polls_list, polls_detail
urlpatterns = [
Expand Down Expand Up @@ -66,7 +66,7 @@ We will now write the :code:`polls_list` and :code:`polls_detail`
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`.
We get a list of dictionaries using :code:`{"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`.

Expand Down Expand Up @@ -95,4 +95,4 @@ Why do we need DRF?
We were able to build the API with just Django, without using DRF, so why do we need DRF?
Almost always, you will need common tasks with your APIs, such as access control, serailization, rate limiting and more.

DRF provides a well thought out set of base components and convinient hook points for building APIs. We will be using DRF in the rest of the chapters.
DRF provides a well thought out set of base components and convenient hook points for building APIs. We will be using DRF in the rest of the chapters.
10 changes: 5 additions & 5 deletions docs/serailizers.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ The first thing we need for our API is to provide a way to serialize model insta
Creating Serializers
-----------------------

Lets get started with creating serializer classes which will serialize and deserialize the model instances to json representations. Create a file named :code:`polls/serializers.py`. We will use :code:`ModelSerializer` which will reduce code duplication by automatically determing the set of fields and by creating implementations of the create() and update() methods.
Lets get started with creating serializer classes which will serialize and deserialize the model instances to json representations. Create a file named :code:`polls/serializers.py`. We will use :code:`ModelSerializer` which will reduce code duplication by automatically determing the set of fields and by creating implementations of the :code:`create()` and :code:`update()` methods.

Our :code:`polls/serializers.py` looks like this.

Expand Down Expand Up @@ -67,8 +67,8 @@ What have we got with this? The :code:`PollSerializer` class has a number of met

* A :code:`is_valid(self, ..)` method which can tell if the data is sufficient and valid to create/update a model instance.
* A :code:`save(self, ..)` method, which khows how to create or update an instance.
* A code:`create(self, validated_data, ..)` method which knows how to create an instance. This method can be overriden to customize the create behaviour.
* A code:`update(self, instance, validated_data, ..)` method which knows how to update an instance. This method can be overriden to customize the update behaviour.
* A :code:`create(self, validated_data, ..)` method which knows how to create an instance. This method can be overriden to customize the create behaviour.
* A :code:`update(self, instance, validated_data, ..)` method which knows how to update an instance. This method can be overriden to customize the update behaviour.


Using the :code:`PollSerializer`
Expand All @@ -78,7 +78,7 @@ Let's use the serializer to create a :code:`Poll` object.

.. code-block:: ipython
In [1]: from polls.serialzers import PollSerializer
In [1]: from polls.serializers import PollSerializer
In [2]: from polls.models import Poll
Expand All @@ -93,7 +93,7 @@ Let's use the serializer to create a :code:`Poll` object.
Out[6]: 5
The :code:`poll.pk` line tells us that the object has been commited to the DB. You can also use the serializer to update a :code:`Poll` object.::
The :code:`poll.pk` line tells us that the object has been commited to the DB. You can also use the serializer to update a :code:`Poll` object. ::


In [9]: poll_serializer = PollSerializer(instance=poll, data={"question": "Mojito, Caipirinha or margarita?", "created_by": 1})
Expand Down
21 changes: 16 additions & 5 deletions docs/setup-models-admin.rst
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ We will use SQlite database, which is already included with Python. The :code:`p
}
}
Now, use the migrate command which builds the needed database tables in regard to the "django_pollsapi/settings.py" file.
Now, use the migrate command which builds the needed database tables in regard to the :code:`django_pollsapi/settings.py` file.

.. code-block:: python
Expand All @@ -63,11 +63,12 @@ Before creating our database models, let us create our pollsapi App.
The above command results in a 'polls' directory containing different files::

admin.py
apps.py
models.py
tests.py
views.py

Step in to 'models.py' file and start writing the models. For creating the polls api we are going to create a :code:`Poll` model, a :code:`Choice` model and a :code:`Vote` model. Once we are done with designing our models, the 'models.py' file should look like this:
Step in to 'models.py' file and start writing the models. For creating the polls api we are going to create a :code:`Poll` model, a :code:`Choice` model and a :code:`Vote` model. Once we are done with designing our models, the :code:'models.py' file should look like this:

These models are the same as you would have seen in the Django introduction tutorial.

Expand Down Expand Up @@ -122,8 +123,11 @@ Now, run the :code:`makemigrations` command which will notify Django that new mo

.. code-block:: python
python manage.py makemigrations polls
python manage.py migrate
$ python manage.py makemigrations polls
$ python manage.py migrate
Create an empty :code:`urls.py` in your :code:`polls` app.

Expand All @@ -139,9 +143,16 @@ Go to :code:`pollsapi/urls.py` and include the polls urls.
.. code-block:: python
urlpatterns = [
url(r'^', include('polls.urls')),
re_path(r'^', include('polls.urls')),
]
Now you can runserver ::

$ python manage.py runserver


Goto any browser of your choice and hit the url :code:`http://127.0.0.1:8000`

And we are in business, with a Django *Congratulations* page greeting us. (Though we haven't added any API endpoints yet.)

.. image:: congrats.png
Expand Down
14 changes: 10 additions & 4 deletions docs/views-and-generic-views.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,26 @@ Creating Views with :code:`APIView`
-----------------------------------------


To start with, we will use the :code:`APIView` to build the polls list and poll detail API we built in the chapter, doc:apis-without-drf:.
To start with, we will use the :code:`APIView` to build the polls list and poll detail API we built in the chapter, :doc:`apis-without-drf`.

Add this to a new file :code:`polls/apiviews.py`

.. code-block:: python
from rest_framework.views import APIView
from rest_framework.response import Response
from django.shortcuts import get_object_or_404
from .models import Poll, Choice
from .serializers import PollSerializer
class PollList(APIView):
def get(self, request):
polls = Poll.objects.all()[:20]
data = PollSerializer(polls, many=True).data
return Response(data)
class PollDetail(APIView):
def get(self, request, pk):
poll = get_object_or_404(Poll, pk=pk)
Expand Down Expand Up @@ -75,7 +81,7 @@ Using DRF generic views to simplify code
-----------------------------------------


The :code:`PollList` and :code:`PollDetail` get the work done, but there are bunch of common operations, we can abstract away.
The :code:`PollList` and :code:`PollDetail` get the work done, but there are bunch of common operations, we can do it in abstract away.

The generic views of Django Rest Framework help us in code reusablity. They infer the response format and allowed methods from the serilizer class and base class.

Expand Down Expand Up @@ -211,7 +217,7 @@ Conect the new apiviews to urls.py.
There is a lot going on here, let us look at the attributes we need to override or set.

- :code:`queryset`: This determines the initial queryset. The queryset can be fulter filtered, sliced or ordered by the view.
- :code:`queryset`: This determines the initial queryset. The queryset can be further filtered, sliced or ordered by the view.
- :code:`serializer_class`: This will be used for validating and deserializing the input and for serializing the output.

We have used three different classes from :code:`rest_framework.generic`. The names of the classes are representative of what they do, but lets quickly look at them.
Expand Down

0 comments on commit 115aebf

Please sign in to comment.