$ 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
# 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
# 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
(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()),
]
(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
# 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
(backend) python manage.py runserver
(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
crap todo-frontend
cd todo-frontend
yarn start
Change componentDidMount()
with axios
for example