cft

Django For APIs Notes- Part II

Django for APIs is a project-based guide to building modern APIs with Django & Django REST Framework.


user

Pragati Verma

3 years ago | 3 min read

Django for APIs is a project-based guide to building modern APIs with Django & Django REST Framework. It is suitable for beginners who have never built an API before as well as professional programmers looking for a fast-paced introduction to Django fundamentals and best practices.

These are essential notes and code snippets from the book that help in extending any existing Django website into web API with minimal effort, covering everything from scratch to hosting and API documentation. We'll be discussing the basics of the Django Rest Framework in Part II. Let's begin!

Django Rest Framework

Django creates websites containing webpages, while Django REST Framework creates web APIs which are a collection of URL endpoints containing available HTTP verbs that return JSON.

wsgi.py stands for web server gateway interface and helps Django serve the eventual web pages

There are three main steps to convert your database models into a RESTful API are:

  • a urls.py file for the URL routes
  • a serializers.py file to transform the data into JSON
  • a views.py file to apply logic to each API endpoint

Serializers

A serializer translates data into a format that is easy to consume over the internet, typically JSON and is displayed at an API endpoint.

NOTES:

Always add a __str__ method to provide a human-readable name for each future model instance.
Migration files are a fantastic way to debug applications and you should strive to create a migration file for each small change. If we had updated the models in two different apps and then run python manage.py makemigrations the resulting single migration file would contain data on both apps. That just makes debugging harder. Try to keep your migrations as small as possible.

CORS - Cross-Origin Resource Sharing

Whenever a client interacts with an API hosted on a different domain (mysite.com vs yoursite.com) or port (localhost:3000 vs localhost:8000) there are potential security issues.

Specifically, CORS requires the server to include specific HTTP headers that allow the client to determine if and when cross-domain requests should be allowed.

The easiest way to handle this–-and the one recommended by Django REST Framework–-is to use middleware that will automatically include the appropriate HTTP headers based on our settings.

We use django-cors-headers:

  • add corsheaders to the INSTALLED_APPS
  • add CorsMiddleware above CommonMiddleWare in MIDDLEWARE
  • create a CORS_ORIGIN_WHITELIST

NOTE:

It’s very important that corsheaders.middleware.CorsMiddleware appears in the proper location. That is above django.middleware.common.CommonMiddleware in the MIDDLEWARE setting since middlewares are loaded top-to-bottom.

Permissions

Django REST Framework ships with several out-of-the-box permissions settings that we can use to secure our API. These can be applied at a project-level, a view-level, or at any individual model level.

Add login to the browsable API
This is such a common occurrence that Django REST Framework has a one-line setting to add login and log out directly to the browsable API itself.
Within the project-level urls.py file, add a new URL route that includes rest_framework.urls. Somewhat confusingly, the actual route specified can be anything
we want; what matters is that rest_framework.urls is included somewhere.

Code:

# blog_project/urls.py
from django.urls import include, path

urlpatterns = [
...
path('api-auth/', include('rest_framework.urls')), # new
]

Project-Level Permissions

Django REST Framework ships with a number of built-in project-level permissions settings we can use, including:

  • AllowAny - any user, authenticated or not, has full access
  • IsAuthenticated - only authenticated, registered users have access
  • IsAdminUser - only admins/superusers have access
  • IsAuthenticatedOrReadOnly - unauthorized users can view any page, but only authenticated users have write, edit, or delete privileges

Implementing any of these four settings requires updating the DEFAULT_PERMISSION_CLASSES setting:

# blog_project/settings.py

REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated', # new
]
}

Note:

If a request contains HTTP verbs included in SAFE_METHODS – a tuple containing GET, OPTIONS, and HEAD –then it is a read-only request, and permission is granted.
The generic views will only check the object-level permissions for views that retrieve a single model instance. If you require object-level filtering of list views–for a collection of instances–you’ll need to filter by overriding the initial queryset.

Conclusion:

Setting proper permissions is a very important part of any API. As a general strategy, it is a good idea to set a strict project-level permissions policy such that only authenticated users can view the API. Then make view-level or custom permissions more accessible as needed on specific API endpoints.

Read Part III here

Upvote


user
Created by

Pragati Verma

Intern @BrightMoney | Ex-SDE Intern @DPhi | MLH Fellow | Ex DSC Lead | InOut 7.0 Winner | SIH2020 Winner | Full Stack Web Developer


people
Post

Upvote

Downvote

Comment

Bookmark

Share


Related Articles