Skip to content

Instantly share code, notes, and snippets.

@jonathanvoelkle
Last active October 4, 2018 10:43
Show Gist options
  • Save jonathanvoelkle/93e91b184e024efc7f29b16d6d37e411 to your computer and use it in GitHub Desktop.
Save jonathanvoelkle/93e91b184e024efc7f29b16d6d37e411 to your computer and use it in GitHub Desktop.
Django Rest Framework + React

Django Rest Framework + React

Setup

$ cd ~/Desktop
$ mkdir todo && cd todo
$ mkdir backend && cd backend
$ pipenv install django
$ pipenv shell
(backend) $ django-admin startproject todo_api .
(backend) $ python manage.py startapp todos
(backend) $ python manage.py migrate
# todo_api/settings.py
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',

    'todos', # new line
]
python manage.py runserver

127.0.0.1:8000

Models

# todos/models.py
from django.db import models


class Todo(models.Model):
    title = models.CharField(max_length=200)
    description = models.TextField()

    def __str__(self):
        """A string representation of the model."""
        return self.title
(backend) $ python manage.py makemigrations todos
(backend) $ python manage.py migrate todos
# todos/admin.py
from django.contrib import admin

from .models import Todo

admin.site.register(Todo)
(backend) $ python manage.py createsuperuser
(backend) $ python manage.py runserver

127.0.0.1:8000/admin

Tests

# todos/tests.py
from django.test import TestCase
from .models import Todo


class TodoModelTest(TestCase):

    @classmethod
    def setUpTestData(cls):
        Todo.objects.create(title='first todo')
        Todo.objects.create(description='a description here')

    def test_title_content(self):
        todo = Todo.objects.get(id=1)
        expected_object_name = f'{todo.title}'
        self.assertEquals(expected_object_name, 'first todo')

    def test_description_content(self):
        todo = Todo.objects.get(id=2)
        expected_object_name = f'{todo.description}'
        self.assertEquals(expected_object_name, 'a description here')
(backend) $ python manage.py test

Django Rest Framework

(backend) $ pipenv install djangorestframework
# todo_api/settings.py
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',

    'rest_framework',

    'todos',
]

REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.AllowAny',
    ]
}
# todo_api/urls.py
from django.contrib import admin
from django.urls import include, path


urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/', include('todos.urls')),
]
(backend) $ touch todos/urls.py
# todos/urls.py
from django.urls import path

from . import views

urlpatterns = [
    path('', views.ListTodo.as_view()),
    path('<int:pk>/', views.DetailTodo.as_view()),
]

Serializers

(backend) $ touch todos/serializers.py
# todos/serializers.py
from rest_framework import serializers
from .models import Todo


class TodoSerializer(serializers.ModelSerializer):
    class Meta:
        fields = (
            'id',
            'title',
            'description',
        )
        model = Todo

Views

# todos/views.py
from rest_framework import generics

from .models import Todo
from .serializers import TodoSerializer


class ListTodo(generics.ListCreateAPIView):
    queryset = Todo.objects.all()
    serializer_class = TodoSerializer


class DetailTodo(generics.RetrieveUpdateDestroyAPIView):
    queryset = Todo.objects.all()
    serializer_class = TodoSerializer

Browsable API

(backend) python manage.py runserver

127.0.0.1:8000/api

CORS

(backend) $ pipenv install django-cors-headers
# todo_api/settings.py
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',

    'rest_framework',
    'corsheaders', # new

    'todos',
]

MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware', # new
    'django.middleware.common.CommonMiddleware', # new
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

CORS_ORIGIN_WHITELIST = (
    'localhost:1234/'
)
(backend) $ python manage.py runserver

Frontend

crap todo-frontend
cd todo-frontend
yarn start

127.0.0.1:1234/

DRF + React

Change componentDidMount() with axios for example

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment