├── reactdjango
├── __init__.py
├── wsgi.py
├── urls.py
└── settings.py
├── sampleapp
├── __init__.py
├── migrations
│ └── __init__.py
├── models.py
├── admin.py
├── tests.py
├── views.py
└── apps.py
├── runtime.txt
├── requirements.txt
├── Procfile
├── public
├── favicon.ico
├── manifest.json
└── index.html
├── src
├── index.css
├── App.test.js
├── index.js
├── App.css
├── logo-django.svg
├── App.js
├── logo-react.svg
└── registerServiceWorker.js
├── .gitignore
├── package.json
├── manage.py
└── README.md
/reactdjango/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/sampleapp/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/runtime.txt:
--------------------------------------------------------------------------------
1 | python-3.6.8
2 |
--------------------------------------------------------------------------------
/sampleapp/migrations/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | django>=2.0.8
2 | gunicorn==19.9.0
3 | whitenoise==4.1.2
4 |
--------------------------------------------------------------------------------
/sampleapp/models.py:
--------------------------------------------------------------------------------
1 | from django.db import models
2 |
3 | # Create your models here.
4 |
--------------------------------------------------------------------------------
/Procfile:
--------------------------------------------------------------------------------
1 | release: python manage.py migrate
2 | web: gunicorn reactdjango.wsgi --log-file -
--------------------------------------------------------------------------------
/sampleapp/admin.py:
--------------------------------------------------------------------------------
1 | from django.contrib import admin
2 |
3 | # Register your models here.
4 |
--------------------------------------------------------------------------------
/sampleapp/tests.py:
--------------------------------------------------------------------------------
1 | from django.test import TestCase
2 |
3 | # Create your tests here.
4 |
--------------------------------------------------------------------------------
/sampleapp/views.py:
--------------------------------------------------------------------------------
1 | from django.shortcuts import render
2 |
3 | # Create your views here.
4 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicholaskajoh/React-Django/HEAD/public/favicon.ico
--------------------------------------------------------------------------------
/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | padding: 0;
4 | font-family: sans-serif;
5 | }
6 |
--------------------------------------------------------------------------------
/sampleapp/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class SampleappConfig(AppConfig):
5 | name = 'sampleapp'
6 |
--------------------------------------------------------------------------------
/src/App.test.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import App from './App';
4 |
5 | it('renders without crashing', () => {
6 | const div = document.createElement('div');
7 | ReactDOM.render(, div);
8 | });
9 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import './index.css';
4 | import App from './App';
5 | import registerServiceWorker from './registerServiceWorker';
6 |
7 | ReactDOM.render(, document.getElementById('root'));
8 | registerServiceWorker();
9 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /node_modules
2 | /coverage
3 | /build
4 | /staticfiles
5 | /.vscode
6 |
7 | *.pyc
8 | *.sqlite3
9 | package-lock.json
10 |
11 | .DS_Store
12 | .env
13 | .env.local
14 | .env.development.local
15 | .env.test.local
16 | .env.production.local
17 |
18 | npm-debug.log*
19 | yarn-debug.log*
20 | yarn-error.log*
21 |
--------------------------------------------------------------------------------
/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | }
10 | ],
11 | "start_url": "./index.html",
12 | "display": "standalone",
13 | "theme_color": "#000000",
14 | "background_color": "#ffffff"
15 | }
16 |
--------------------------------------------------------------------------------
/src/App.css:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 |
5 | .App-logo {
6 | animation: App-logo-spin infinite 20s linear;
7 | height: 80px;
8 | }
9 |
10 | .App-header {
11 | background-color: #222;
12 | height: 150px;
13 | padding: 20px;
14 | color: white;
15 | }
16 |
17 | .App-title {
18 | font-size: 1.5em;
19 | }
20 |
21 | .App-intro {
22 | font-size: large;
23 | }
24 |
25 | @keyframes App-logo-spin {
26 | from { transform: rotate(0deg); }
27 | to { transform: rotate(360deg); }
28 | }
29 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-django",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "react": "^16.2.0",
7 | "react-dom": "^16.2.0",
8 | "react-scripts": "1.0.17"
9 | },
10 | "scripts": {
11 | "start": "react-scripts start",
12 | "build": "react-scripts build",
13 | "test": "react-scripts test --env=jsdom",
14 | "eject": "react-scripts eject",
15 | "postinstall": "npm run build"
16 | },
17 | "engines": {
18 | "node": "8.9.4",
19 | "npm": "5.6.0"
20 | },
21 | "homepage": "/assets"
22 | }
23 |
--------------------------------------------------------------------------------
/reactdjango/wsgi.py:
--------------------------------------------------------------------------------
1 | """
2 | WSGI config for reactdjango project.
3 |
4 | It exposes the WSGI callable as a module-level variable named ``application``.
5 |
6 | For more information on this file, see
7 | https://docs.djangoproject.com/en/2.0/howto/deployment/wsgi/
8 | """
9 |
10 | import os
11 |
12 | from django.core.wsgi import get_wsgi_application
13 | from whitenoise.django import DjangoWhiteNoise
14 |
15 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "reactdjango.settings")
16 |
17 | application = get_wsgi_application()
18 | application = DjangoWhiteNoise(application)
--------------------------------------------------------------------------------
/manage.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | import os
3 | import sys
4 |
5 | if __name__ == "__main__":
6 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "reactdjango.settings")
7 | try:
8 | from django.core.management import execute_from_command_line
9 | except ImportError as exc:
10 | raise ImportError(
11 | "Couldn't import Django. Are you sure it's installed and "
12 | "available on your PYTHONPATH environment variable? Did you "
13 | "forget to activate a virtual environment?"
14 | ) from exc
15 | execute_from_command_line(sys.argv)
16 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # React-Django app
2 | Simple setup for a React-Django web app. See tutorial here: https://alphacoder.xyz/dead-simple-react-django-setup.
3 |
4 | ## Setup
5 | - Download/clone repo.
6 | - Create and activate a virtual environment.
7 | - Install Django and other dependencies with `pip install -r requirements.txt`.
8 | - Run Django app using `python manage.py runserver`.
9 | - Install React dependencies with `npm install`.
10 | - Run React app with `npm start`.
11 | - Build React app using `npm run build`.
12 |
13 | ## Deploy
14 | Read my tutorial on deploying this app to Heroku here: https://alphacoder.xyz/deploy-react-django-app-on-heroku.
15 |
--------------------------------------------------------------------------------
/src/logo-django.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/App.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import reactLogo from './logo-react.svg';
3 | import djangoLogo from './logo-django.svg';
4 | import './App.css';
5 |
6 | class App extends Component {
7 | render() {
8 | return (
9 |
10 |
11 |
12 |
13 | Welcome to the React-Django app
14 |
15 |
16 | I'm a blank canvas waiting for a coder's touch!
17 |
18 |
19 | );
20 | }
21 | }
22 |
23 | export default App;
24 |
--------------------------------------------------------------------------------
/reactdjango/urls.py:
--------------------------------------------------------------------------------
1 | """reactdjango URL Configuration
2 |
3 | The `urlpatterns` list routes URLs to views. For more information please see:
4 | https://docs.djangoproject.com/en/2.0/topics/http/urls/
5 | Examples:
6 | Function views
7 | 1. Add an import: from my_app import views
8 | 2. Add a URL to urlpatterns: path('', views.home, name='home')
9 | Class-based views
10 | 1. Add an import: from other_app.views import Home
11 | 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
12 | Including another URLconf
13 | 1. Import the include() function: from django.urls import include, path
14 | 2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
15 | """
16 | from django.contrib import admin
17 | from django.urls import path, re_path
18 | from django.views.generic import TemplateView
19 |
20 | urlpatterns = [
21 | path('admin/', admin.site.urls),
22 | # path('api/', include('sampleapp.urls')),
23 | re_path('.*', TemplateView.as_view(template_name='index.html')),
24 | ]
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
11 |
12 |
13 |
22 | React App
23 |
24 |
25 |
28 |
29 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/src/logo-react.svg:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/reactdjango/settings.py:
--------------------------------------------------------------------------------
1 | """
2 | Django settings for reactdjango project.
3 |
4 | Generated by 'django-admin startproject' using Django 2.0.
5 |
6 | For more information on this file, see
7 | https://docs.djangoproject.com/en/2.0/topics/settings/
8 |
9 | For the full list of settings and their values, see
10 | https://docs.djangoproject.com/en/2.0/ref/settings/
11 | """
12 |
13 | import os
14 |
15 | # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
16 | BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
17 |
18 |
19 | # Quick-start development settings - unsuitable for production
20 | # See https://docs.djangoproject.com/en/2.0/howto/deployment/checklist/
21 |
22 | # SECURITY WARNING: keep the secret key used in production secret!
23 | SECRET_KEY = '463hzk*onkb4h&+j@mof$wc(20t$$l17w#(v8-6ipzq7m=$a=j'
24 |
25 | # SECURITY WARNING: don't run with debug turned on in production!
26 | DEBUG = True
27 |
28 | ALLOWED_HOSTS = ['react-django.herokuapp.com', '127.0.0.1']
29 |
30 |
31 | # Application definition
32 |
33 | INSTALLED_APPS = [
34 | 'sampleapp',
35 |
36 | 'django.contrib.admin',
37 | 'django.contrib.auth',
38 | 'django.contrib.contenttypes',
39 | 'django.contrib.sessions',
40 | 'django.contrib.messages',
41 | 'django.contrib.staticfiles',
42 | ]
43 |
44 | MIDDLEWARE = [
45 | 'django.middleware.security.SecurityMiddleware',
46 | 'django.contrib.sessions.middleware.SessionMiddleware',
47 | 'django.middleware.common.CommonMiddleware',
48 | 'django.middleware.csrf.CsrfViewMiddleware',
49 | 'django.contrib.auth.middleware.AuthenticationMiddleware',
50 | 'django.contrib.messages.middleware.MessageMiddleware',
51 | 'django.middleware.clickjacking.XFrameOptionsMiddleware',
52 | ]
53 |
54 | ROOT_URLCONF = 'reactdjango.urls'
55 |
56 | TEMPLATES = [
57 | {
58 | 'BACKEND': 'django.template.backends.django.DjangoTemplates',
59 | 'DIRS': [
60 | os.path.join(BASE_DIR, 'build')
61 | ],
62 | 'APP_DIRS': True,
63 | 'OPTIONS': {
64 | 'context_processors': [
65 | 'django.template.context_processors.debug',
66 | 'django.template.context_processors.request',
67 | 'django.contrib.auth.context_processors.auth',
68 | 'django.contrib.messages.context_processors.messages',
69 | ],
70 | },
71 | },
72 | ]
73 |
74 | WSGI_APPLICATION = 'reactdjango.wsgi.application'
75 |
76 |
77 | # Database
78 | # https://docs.djangoproject.com/en/2.0/ref/settings/#databases
79 |
80 | DATABASES = {
81 | 'default': {
82 | 'ENGINE': 'django.db.backends.sqlite3',
83 | 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
84 | }
85 | }
86 |
87 |
88 | # Password validation
89 | # https://docs.djangoproject.com/en/2.0/ref/settings/#auth-password-validators
90 |
91 | AUTH_PASSWORD_VALIDATORS = [
92 | {
93 | 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
94 | },
95 | {
96 | 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
97 | },
98 | {
99 | 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
100 | },
101 | {
102 | 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
103 | },
104 | ]
105 |
106 |
107 | # Internationalization
108 | # https://docs.djangoproject.com/en/2.0/topics/i18n/
109 |
110 | LANGUAGE_CODE = 'en-us'
111 |
112 | TIME_ZONE = 'UTC'
113 |
114 | USE_I18N = True
115 |
116 | USE_L10N = True
117 |
118 | USE_TZ = True
119 |
120 |
121 | # Static files (CSS, JavaScript, Images)
122 | # https://docs.djangoproject.com/en/2.0/howto/static-files/
123 |
124 | STATIC_URL = '/assets/'
125 |
126 | STATICFILES_DIRS = [
127 | os.path.join(BASE_DIR, 'build'),
128 | ]
129 |
130 | STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
131 |
132 | STATICFILES_STORAGE = 'whitenoise.django.GzipManifestStaticFilesStorage'
--------------------------------------------------------------------------------
/src/registerServiceWorker.js:
--------------------------------------------------------------------------------
1 | // In production, we register a service worker to serve assets from local cache.
2 |
3 | // This lets the app load faster on subsequent visits in production, and gives
4 | // it offline capabilities. However, it also means that developers (and users)
5 | // will only see deployed updates on the "N+1" visit to a page, since previously
6 | // cached resources are updated in the background.
7 |
8 | // To learn more about the benefits of this model, read https://goo.gl/KwvDNy.
9 | // This link also includes instructions on opting out of this behavior.
10 |
11 | const isLocalhost = Boolean(
12 | window.location.hostname === 'localhost' ||
13 | // [::1] is the IPv6 localhost address.
14 | window.location.hostname === '[::1]' ||
15 | // 127.0.0.1/8 is considered localhost for IPv4.
16 | window.location.hostname.match(
17 | /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
18 | )
19 | );
20 |
21 | export default function register() {
22 | if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
23 | // The URL constructor is available in all browsers that support SW.
24 | const publicUrl = new URL(process.env.PUBLIC_URL, window.location);
25 | if (publicUrl.origin !== window.location.origin) {
26 | // Our service worker won't work if PUBLIC_URL is on a different origin
27 | // from what our page is served on. This might happen if a CDN is used to
28 | // serve assets; see https://github.com/facebookincubator/create-react-app/issues/2374
29 | return;
30 | }
31 |
32 | window.addEventListener('load', () => {
33 | const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
34 |
35 | if (isLocalhost) {
36 | // This is running on localhost. Lets check if a service worker still exists or not.
37 | checkValidServiceWorker(swUrl);
38 | } else {
39 | // Is not local host. Just register service worker
40 | registerValidSW(swUrl);
41 | }
42 | });
43 | }
44 | }
45 |
46 | function registerValidSW(swUrl) {
47 | navigator.serviceWorker
48 | .register(swUrl)
49 | .then(registration => {
50 | registration.onupdatefound = () => {
51 | const installingWorker = registration.installing;
52 | installingWorker.onstatechange = () => {
53 | if (installingWorker.state === 'installed') {
54 | if (navigator.serviceWorker.controller) {
55 | // At this point, the old content will have been purged and
56 | // the fresh content will have been added to the cache.
57 | // It's the perfect time to display a "New content is
58 | // available; please refresh." message in your web app.
59 | console.log('New content is available; please refresh.');
60 | } else {
61 | // At this point, everything has been precached.
62 | // It's the perfect time to display a
63 | // "Content is cached for offline use." message.
64 | console.log('Content is cached for offline use.');
65 | }
66 | }
67 | };
68 | };
69 | })
70 | .catch(error => {
71 | console.error('Error during service worker registration:', error);
72 | });
73 | }
74 |
75 | function checkValidServiceWorker(swUrl) {
76 | // Check if the service worker can be found. If it can't reload the page.
77 | fetch(swUrl)
78 | .then(response => {
79 | // Ensure service worker exists, and that we really are getting a JS file.
80 | if (
81 | response.status === 404 ||
82 | response.headers.get('content-type').indexOf('javascript') === -1
83 | ) {
84 | // No service worker found. Probably a different app. Reload the page.
85 | navigator.serviceWorker.ready.then(registration => {
86 | registration.unregister().then(() => {
87 | window.location.reload();
88 | });
89 | });
90 | } else {
91 | // Service worker found. Proceed as normal.
92 | registerValidSW(swUrl);
93 | }
94 | })
95 | .catch(() => {
96 | console.log(
97 | 'No internet connection found. App is running in offline mode.'
98 | );
99 | });
100 | }
101 |
102 | export function unregister() {
103 | if ('serviceWorker' in navigator) {
104 | navigator.serviceWorker.ready.then(registration => {
105 | registration.unregister();
106 | });
107 | }
108 | }
109 |
--------------------------------------------------------------------------------