First, a few resources: read more about API endpoints in this previous blog post and review documentation on Django Rest Framework.,With a model created, we can move on to creating a serializer for handling the data going in and out of our app for the Company model.,A typical request for an API endpoint may be something like: 'the front end app needs to be able to read, create, and update companies through the API'. Here is a summary of creating a model, a serializer, and a view for such a scenario, including tests for each part:,Now we have an API endpoint that allows making GET, POST, PUT, and PATCH requests to read, create, and update Company objects. In order to make sure it works just as we expect, we add some tests:
# models.py
from django.db
import models
class Company(models.Model):
name = models.CharField(max_length = 255)
description = models.TextField(blank = True)
website = models.URLField(blank = True)
street_line_1 = models.CharField(max_length = 255)
street_line_2 = models.CharField(max_length = 255, blank = True)
city = models.CharField(max_length = 80)
state = models.CharField(max_length = 80)
zipcode = models.CharField(max_length = 10)
def __str__(self):
return self.name
# tests / factories.py
from factory
import DjangoModelFactory, Faker
from..models
import Company
class CompanyFactory(DjangoModelFactory):
name = Faker('company')
description = Faker('text')
website = Faker('url')
street_line_1 = Faker('street_address')
city = Faker('city')
state = Faker('state_abbr')
zipcode = Faker('zipcode')
class Meta:
model = Company
# tests / test_models.py
from django.test
import TestCase
from..models
import Company
from.factories
import CompanyFactory
class CompanyTestCase(TestCase):
def test_str(self):
""
"Test for string representation."
""
company = CompanyFactory()
self.assertEqual(str(company), company.name)
# serializers.py
from rest_framework.serializers
import ModelSerializer
from.models
import Company
class CompanySerializer(ModelSerializer):
class Meta:
model = Company
fields = (
'id', 'name', 'description', 'website', 'street_line_1', 'street_line_2',
'city', 'state', 'zipcode'
)
# tests / test_serializers.py
from django.test
import TestCase
from..serializers
import CompanySerializer
from.factories
import CompanyFactory
class CompanySerializer(TestCase):
def test_model_fields(self):
""
"Serializer data matches the Company object for each field."
""
company = CompanyFactory()
for field_name in [
'id', 'name', 'description', 'website', 'street_line_1', 'street_line_2',
'city', 'state', 'zipcode'
]:
self.assertEqual(
serializer.data[field_name],
getattr(company, field_name)
)
# views.py
from rest_framework.mixins import(
CreateModelMixin, ListModelMixin, RetrieveModelMixin, UpdateModelMixin
)
from rest_framework.viewsets
import GenericViewSet
from.models
import Company
from.serializers
import CompanySerializer
class CompanyViewSet(GenericViewSet, # generic view functionality CreateModelMixin, # handles POSTs RetrieveModelMixin, # handles GETs
for 1 Company UpdateModelMixin, # handles PUTs and PATCHes ListModelMixin): # handles GETs
for many Companies
serializer_class = CompanySerializer
queryset = Company.objects.all()
Create a new Django project named tutorial, then start a new app called quickstart.,Right, we'd better write some views then. Open tutorial/quickstart/views.py and get typing.,We're going to create a simple API to allow admin users to view and edit the users and groups in the system.,Rather than write multiple views we're grouping together all the common behavior into classes called ViewSets.
Create a new Django project named tutorial
, then start a new app called quickstart
.
# Create the project directory mkdir tutorial cd tutorial # Create a virtual environment to isolate our package dependencies locally python3 - m venv env source env / bin / activate # On Windows use `env\Scripts\activate` # Install Django and Django REST framework into the virtual environment pip install django pip install djangorestframework # Set up a new project with a single application django - admin startproject tutorial.# Note the trailing '.' character cd tutorial django - admin startapp quickstart cd..
The project layout should look like:
$ pwd
<some path>/tutorial
$ find .
.
./manage.py
./tutorial
./tutorial/__init__.py
./tutorial/quickstart
./tutorial/quickstart/__init__.py
./tutorial/quickstart/admin.py
./tutorial/quickstart/apps.py
./tutorial/quickstart/migrations
./tutorial/quickstart/migrations/__init__.py
./tutorial/quickstart/models.py
./tutorial/quickstart/tests.py
./tutorial/quickstart/views.py
./tutorial/asgi.py
./tutorial/settings.py
./tutorial/urls.py
./tutorial/wsgi.py
Now sync your database for the first time:
python manage.py migrate
First up we're going to define some serializers. Let's create a new module named tutorial/quickstart/serializers.py
that we'll use for our data representations.
from django.contrib.auth.models
import User, Group
from rest_framework
import serializers
class UserSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = User
fields = ['url', 'username', 'email', 'groups']
class GroupSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Group
fields = ['url', 'name']
Right, we'd better write some views then. Open tutorial/quickstart/views.py
and get typing.
from django.contrib.auth.models import User, Group from rest_framework import viewsets from rest_framework import permissions from tutorial.quickstart.serializers import UserSerializer, GroupSerializer class UserViewSet(viewsets.ModelViewSet): "" " API endpoint that allows users to be viewed or edited. "" " queryset = User.objects.all().order_by('-date_joined') serializer_class = UserSerializer permission_classes = [permissions.IsAuthenticated] class GroupViewSet(viewsets.ModelViewSet): "" " API endpoint that allows groups to be viewed or edited. "" " queryset = Group.objects.all() serializer_class = GroupSerializer permission_classes = [permissions.IsAuthenticated]
Let's start off by initializing a virtual environment, for the sake of organizing dependencies and their effects on other dependencies, and activating it:
$ mkdir drf_tutorial $ cd drf_tutorial $ python3 - m venv env $ env\ scripts\ activate # Windows $.env / bin / activate # MAC or Linux
Then, we can install Django and the Django REST Framework, within that environment:
$ pip install django $ pip install djangorestframework
Finally, we can create a project and app, called api_app
:
$ django - admin startproject shopping_cart $ cd shopping_cart # Project contains app $ python3 manage.py startapp api_app
Once registered, we can apply the migration (initialize the database) and create a superuser to keep an eye on the database:
$ python3 manage.py migrate # Initialize database $ python3 manage.py createsuperuser # Prompts for username and password
With a superuser in place and app registered, we can start the server to accept requests! This is easily done via the runserver
command, from within manage.py
:
$ python3 manage.py runserver
March 3, 2022 6 min read 1917
Navigate to an empty folder in your terminal and install Django and Django REST framework in your project with the commands below:
pip install django pip install django_rest_framework
Create a Django project called todo
with the following command:
django - admin startproject todo
Then, cd
into the new todo
folder and create a new app for your API:
django - admin startapp todo_api
Next, add rest_framework
and todo
to the INSTALLED_APPS
inside the todo/todo/settings.py
file:
# settings.py INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'rest_framework', 'todo_api' ]
Create a serializers.py
and urls.py
file in todo/todo_api
and add new files as configured in the directory structure below:
├── todo│├── __init__.py│├── settings.py│├── urls.py├── db.sqlite3├── manage.py└── todo_api├── admin.py├── serializers.py├── __init__.py├── models.py├── urls.py└── views.py