Django: Difference between revisions
Jump to navigation
Jump to search
Line 1: | Line 1: | ||
=Setting up REST API within Django= | =Setting up REST API within Django= | ||
These are just notes from a demo | These are just notes from a demo | ||
=Django= | |||
=Create a Django Project= | =Create a Django Project= | ||
Follow steps on https://www.django-rest-framework.org/tutorial/quickstart/#project-setup | Follow steps on https://www.django-rest-framework.org/tutorial/quickstart/#project-setup |
Revision as of 23:27, 6 January 2021
Setting up REST API within Django
These are just notes from a demo
Django
Create a Django Project
Follow steps on https://www.django-rest-framework.org/tutorial/quickstart/#project-setup
Create a Container
We can build a container using docker-compose. Create a docker file with
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
Create a requirements.txt document
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
Login to Container
Login to the container with
docker-compose exec backend bash
Create an App
python manage.py startapp products
Amend the Settings on the container
We need to modify the following sections
INSTALLED_APPS = [
...
'django.contrib.staticfiles',
'rest_framework',
'corsheaders',
'products'
]
MIDDLEWARE = [
...
'django.contrib.sessions.middleware.SessionMiddleware',
'corsheaders.middleware.CorsMiddleware',
...
]
...
# Database
# https://docs.djangoproject.com/en/3.1/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'admin',
'USER': 'root',
'PASSWORD': 'root',
'HOST': 'db',
'PORT': '3306'
}
}
...
CORS_ALLOW_ALL_ORIGINS = True
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)