In this tutorial, you will be learning how to create a todo app using Django/Python and drf (django rest framework).
Let's get started:
We have to install some tools:
I will assume you already have pip and python installed.
pip install pipenv
- to install a virtual environment.
pipenv shell
- creates/springs up a virtual environment for your app.
pipenv install django~=3.1.0
- to install the django package.
pipenv install djangorestframework~=3.11
- to install the django rest framework.
pipenv install psycopg2~=2.8.5
- for database connection.
Run django-admin startproject <name of app>
- creates a new app folder with its config/settings/details.
I will assume that you have postgres installed, create a new database called: todoapp
and add the following piece of code to the .env file.
db_name=todoapp
db_user=<postgres-user>
db_password=<postgres-password>
Then in the settings file,
Add the following piece of code for database connectivity:
import os
- at the top of the file.
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
- to build the path.
- replace the database configuration with the following piece of code to enable us use postgres.
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': os.getenv('db_name'),
'PASSWORD': os.getenv('db_password'),
'USER': os.getenv('db_user'),
'PORT': '5432',
'HOST': 'localhost'
}
}
add rest_framework
and todoapp
- to the INSTALLED_APPS right under the other ones there.
INSTALLED_APPS = [
'rest_framework',
'todoapp'
]
cd into the newly created app/folder(todoapp) and run
python manage.py makemigrations todoapp
to migrate and propagate new changes.python manage.py migrate todoapp
to migrate files into the databasepython manage.py runserver
to start up the server. You can view this in your browser using the url.
In the todoapp folder, where the settings file is, create a new file called models.py
and add the following code:
from django.db import models
class NoteModel(models.Model):
title = models.CharField(max_length=100)
description = models.CharField(max_length=200)
tags = models.CharField(max_length=300)
def __str__(self):
return self.title
Note:
- from
django.db
import models - attributes are created which is mapped to a database column
Read more here: docs.djangoproject.com/en/3.1/topics/db/mod..
create another file called serializers.py
and add the following code:
from django.contrib.postgres.fields import ArrayField
from rest_framework import serializers
from .models import NoteModel
class NoteSerializer(serializers.ModelSerializer):
title = serializers.CharField(max_length=100)
description = serializers.CharField(max_length=200)
tags = ArrayField(
serializers.CharField(max_length=300), default=list)
class Meta:
model = NoteModel
fields = ['title', 'description', 'tags']
Note:
- the
ArrayField
is imported to enable us to add an array of items(tags) to the database. - serializers are imported from django rest framework.
- also, the created model is imported.
- we declare serializers that can help us to serialize data.
create another file called views.py
and add the following code:
from rest_framework import status
from rest_framework.views import APIView
from rest_framework.response import Response
from .models import NoteModel
from .serializers import NoteSerializer
class NoteView(APIView):
"""
Create a new note
"""
def post(self, request):
serializer = NoteSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
"""
Get all notes
"""
def get(self, request):
notes = NoteModel.objects.all()
serializer = NoteSerializer(notes, many=True)
return Response(serializer.data, status=status.HTTP_200_OK)
class NoteDetailView(APIView):
"""
Get a note
"""
def get_object(self, pk):
try:
return NoteModel.objects.get(pk=pk)
except NoteModel.DoesNotExist:
raise Http404
def get(self, request, pk, format=None):
note = self.get_object(pk)
serializer = NoteSerializer(note)
return Response(serializer.data)
"""
Update a note
"""
def put(self, request, pk, format=None):
note = self.get_object(pk)
serializer = NoteSerializer(note, data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
"""
Delete a note
"""
def delete(self, request, pk, format=None):
note = self.get_object(pk)
note.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
Note:
- we are making use of the django rest framework's class-based views.
- the created models and serializers are created.
- two classes are created called
NoteView
andNoteDetailView
. - for the class
NoteView
, two methods are created forpost
to create a new note andget
to get all notes. - then for the class
NoteDetailView
, three methods are created forput
to update a note,delete
to delete a note andget
to get a single note.
Read more about the methods on the official docs: django-rest-framework.org/tutorial/3-class-..
We have to create URLs for the created methods, add the following code:
from django.urls import path
from rest_framework.urlpatterns import format_suffix_patterns
from .views import NoteView, NoteDetailView
urlpatterns = [
path('notes', NoteView.as_view()),
path('note/<int:pk>', NoteDetailView.as_view()),
]
urlpatterns = format_suffix_patterns(urlpatterns)
Run python manage.py runserver
to start your server and test the endpoints.
For the code repo: github.com/codeliezel/django-drf-todo
That marks the end of this tutorial.