Django
Setting up REST API within Django
These are just notes from a demo
Useful Commands
Login to Container
Login to the container with
docker-compose exec backend bash
Creating A Container With Composer
- Create a requirements.txt document with what is required for the container
- Create a Docker File definition
- Create a composer file
Requirements
This will differ from app to app below are examples for Django and Flask
Docker File
Again this will differ from app to app Here is a docker file to support Dango on for 8000
FROM python:3.9
ENV PYTHONNUMBUFFERED 1
WORKDIR /app
COPY requirements.txt /app/requirements.txt
RUN pip install -r requirements.txt
COPY . /app
CMD python manage.py runserver 0.0.0.0:8000
Composer File
Here is the composer file for Dango
FROM python:3.9
ENV PYTHONNUMBUFFERED 1
WORKDIR /app
COPY requirements.txt /app/requirements.txt
RUN pip install -r requirements.txt
COPY . /app
CMD python manage.py runserver 0.0.0.0:8000
Next write a yaml to install software
version: '3.8'
services:
backend:
build:
context: .
dockerfile: Dockerfile
ports:
- 8000:8000
volumes:
- .:/app
depends_on:
- db
db:
image: mysql:5.7.32
restart: always
environment:
MYSQL_DATABASE: admin
MYSQL_USER: root
MYSQL_PASSWORD: root
MYSQL_ROOT_PASSWORD: root
volumes:
- .dbdata:/var/lib/nysql
ports:
- 33066:3306
Django Container
Requirements
Django==3.1.5
djangorestframework==3.12.2
mysqlclient==2.0.3
django-mysql==3.10.0
django-cors-headers==3.6.0
pika==1.1.0
We can build a container using docker-compose. Create a docker file with
<br>
=Django=
On the container you need to define the app
==Create and Setup App==
<syntaxhighlight lang="bash">
python manage.py startapp products
Create Model Classes
Edit the model classes under the Product app
from django.db import models
# Create your models here.
class Product(models.Model):
title = models.CharField(max_length=200)
image = models.CharField(max_length=200)
likes = models.PositiveIntegerField(default=0)
class User(models.Model):
pass
Run the Migrations
This will create the tables. Log back into the container and type
python manage.py makemigrations
python manage.py migrate
Make Serializers
We make serializer for the product table with
from django.db import models
from rest_framework import serializers
from .models import Product
class ProductSerializer(serializers.ModelSerializer):
class Meta:
model = Product
fields = '__all__'
Make Url (Routing)
In the main routing add the api route with an include
urlpatterns = [
path('admin/', admin.site.urls),
path('api/', include('products.urls'))
]
In the app we can now add routes for the REST end points. Which are just maps to the views.
from django.urls import path
from .views import ProductViewSet
urlpatterns = [
path('products', ProductViewSet.as_view({
'get' : 'list',
'post': 'create'
})),
path( 'products/<int:pk>', ProductViewSet.as_view({
'get' : 'retreive',
'put': 'update',
'delete': 'destroy'
}))
]
Make Views (Repository or Data Layer)
This is like the repository layer and provides the CRUD functions to support the routing.
from django.shortcuts import render
# Create your views here.
from rest_framework import viewsets, status
from rest_framework.response import Response
from rest_framework.serializers import Serializer
from .models import Product
from .serializer import ProductSerializer
class ProductViewSet(viewsets.ViewSet):
def list(self, request): # /api/products/<str:id>
products = Product.objects.all()
serializer = ProductSerializer(products, many=True)
return Response(serializer.data)
def create(self, request): # /api/products
serializer = ProductSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
def retreive(self, request, pk=None): # /api/products/<str:id>
product = Product.objects.get(id=pk)
serializer =ProductSerializer(product)
return Response(serializer.data)
def update(self, request, pk=None): # /api/products/<str:id>
product = Product.objects.get(id=pk)
serializer =ProductSerializer(instance=product, data=request.data)
serializer.is_valid(raise_exception=True)
serializer.save()
return Response(serializer.data, status=status.HTTP_202_ACCEPTED)
def destroy(self, request, pk=None): # /api/products/<str:id>
product = Product.objects.get(id=pk)
product.delete()
return Response(status=status.HTTP_204_NO_CONTENT)