Django: Difference between revisions

From bibbleWiki
Jump to navigation Jump to search
Line 12: Line 12:
==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
==Create a Container==
We can build a container using docker-compose. Create a docker file with
<syntaxhighlight lang="Dockerfile">
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
</syntaxhighlight>
<br>
Next write a yaml to install software
<syntaxhighlight lang="yaml">
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
</syntaxhighlight>
<br>
Create a requirements.txt document
<syntaxhighlight lang="bash">
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
</syntaxhighlight>


=Create an App=
=Create an App=

Revision as of 23:29, 6 January 2021

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

Django

Create a Django Project

Follow steps on https://www.django-rest-framework.org/tutorial/quickstart/#project-setup

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)