Demo: https://youtu.be/0VhKaPFDnRA
Notes app using django + react integration.
for a real production case, it is a good practice to do backend & frontend in separate repos. But in this case due it's a small project and it is for practice, I will kept both in the same repo.
- Create a virtual environment
python3 -m venv .venvinside the virtual environment
pip install django django-admin startproject notes_app python manage.py runserver python manage.py startapp apiInitial migrations from django
python manage.py migratemigrate the changes to the db
python manage.py makemigrationsconvert our new Note model into a table in our database
python manage.py migrate python manage.py createsuperuser # api/admin.py
from django.contrib import admin
from .models import Note
admin.site.register(Note)Django REST framework is a powerful and flexible toolkit for building Web APIs. we could do all this manually, but it would be a lot of work. Instead, we can use Django REST framework to handle the serialization for us.
pip install djangorestframework # notes_app/settings.py
INSTALLED_APPS = [
...
'rest_framework',
]This time will use create react app, maybe in a real use case I shouldn't use it, but for this case is ok.
npx create-react-app frontendhttps://pypi.org/project/django-cors-headers/
pip install django-cors-headers # notes_app/settings.py
INSTALLED_APPS = [
...
'corsheaders',
] # notes_app/settings.py
MIDDLEWARE = [
...
'corsheaders.middleware.CorsMiddleware',
# 'django.middleware.common.CommonMiddleware',
] # notes_app/settings.py
CORS_ALLOWED_ORIGINS = [] # allow only whitelisted origins
# or
CORS_ORIGIN_ALLOW_ALL = True # allow all origins
# or
CORS_ORIGIN_WHITELIST = [] # allow only whitelisted origins
# or
CORS_ORIGIN_REGEX_WHITELIST = [] # allow only whitelisted origins with regex
# orhttps://reactrouter.com/web/guides/quick-start
npm install react-router-domHaving the frontend & backend in the same URL, so we can use the same domain for both. This means if I go to 127.0.0.1:8000 I should see the frontend. And if I go to 127.0.0.1:8000/api/ I should see the backend.
move the frontend folder to the root of the django project
The build is in the .gitignore so will have tu build it manually in every branch
npm run build # notes_app/settings.py
TEMPLATES = [
{
...
'DIRS': [
BASE_DIR / 'frontend/build'
],
...
},
] # notes_app/settings.py
STATICFILES_DIRS = [
BASE_DIR / 'frontend/build/static'
] # notes_app/urls.py
from django.views.generic import TemplateView
urlpatterns = [
...
path('', TemplateView.as_view(template_name='index.html')),
] python manage.py runserver
# will run both backend & frontend (django & react)what happens in this bug is that if you go to an specific route, it will show 404 because django is looking for that route, but it doesn't exist because React is who is handling the routes. This is fixed with:
# notes_app/urls.py
from django.views.generic import TemplateView
urlpatterns = [
...
path('', TemplateView.as_view(template_name='index.html')),
path('<path:path>', TemplateView.as_view(template_name='index.html')),
] // frontend/src/App.js
import { HashRouter as Router, Route, Routes } from 'react-router-dom'
// change BrowserRouter to HashRouterthis will show a # in every react route, may not look good, but it works.
I got a bug when trying to solve the react router url bug, this was a cache bug, so using the first solution gave me more problems, the real solution was to use the second one(the # solution), but I had to clear the cache of the browser to make it work.
means for example, having GET & POST in the same URL, and not going separately like we used before:
Restful practica example:
/notes GET
/notes POST
or with a detail view:
/notes/<id> GET
/notes/<id> PUT
/notes/<id> DELETE
Not Restful practica example:
/notes GET
/notes/create POST
or with a detail view:
/notes/<id> GET
/notes/<id>/update PUT
/notes/<id>/delete DELETE