A little Python module helping to use Django and React on a single port during development and production
Project description
logicore-django-react
A little Python module helping to use Django and React on a single port during development and production
Serves as a foundation for logicore-django-react-pages project, but can be used without it
Running Django and React on a single port during development
TODO: Motivation
Usage from scratch: starting a Django + React project for development
TODO: automated script/project template
- Install Django and start the project
mkvirtualenv django_react_project1 # Or venv etc
python3 -m pip install Django
django-admin.py startproject django_react_project1
cd django_react_project1
# Configure database, etc and commit
Now you have fresh Django! Check it works:
python manage.py runserver
and stop the development server.
Hint: Don't forget to add minimal .gitignore file for Python/Django development, such as:
*.swp
*.py[cod]
__pycache__
*.sqlite3
/static/**
/media/**
- Make a React for-development installation (inside a Django folder), called
frontend. Then, commit the changes and eject (we need it all):
create-react-app frontend
git add --all :/ && git commit -m "added frontend"
cd frontend
yarn eject
git add --all :/ && git commit -m "ejected frontend"
- Install
logicore_django_reactand make use of it from your Django project:
pip install -U logicore_django_react
(-U is required to ensure to get latest version)
Add to urls.py:
from logicore_django_react.urls import react_reload_and_static_urls, react_html_template_urls
urlpatterns = [
# ...
]
# add static/media endpoints here if needed
# urlpatterns += static(...)
# lastly, combine with logicore_django_react urls
urlpatterns = react_reload_and_static_urls + urlpatterns + react_html_template_urls
Which will add necessary views for React to work via Django:
react_reload_and_static_urls— serves hot-reload hooks and static filesreact_html_template_urls— global (aka match-all,.*) view, that just serves HTML template that includes React
The latter (HTML template) might be overridden by changing
the LOGICORE_DJANGO_REACT_TEMPLATE setting, which is by default set to
logicore_django_react/home.html filename.
Please see source of a corresponding template file as an example.
Important: In order for template file and template tags to work, add logicore_django_react to INSTALLED_APPS.
Also to settings, add:
FRONTEND_DEV_MODE = os.environ.get("FRONTEND_DEV_MODE", None)
(otherwise you may see an error message).
This environment variable is required to distinguish if Django is running in development or production mode.
- Either:
- create your main app in Django (e.g. called
main) - or add non-app templates and static folders
to prepare for React build bundles (templates and static files) to be saved into and remember it for the next step:
python manage.py startapp main # and add to INSTALLED_APPS
mkdir main/templates/ # here, "react" folder will automatically be added later
mkdir main/static/ # here, "react" folder will automatically be added later
or
# add "my_global_templates" to TEMPLATE_DIRS
mkdir my_global_templates/ # here, "react" folder will automatically be added later
# add "my_global_static" to STATICFILES_DIRS
mkdir my_global_static/ # here, "react" folder will automatically be added later
Hints:
- When creating an app, don't forget to add it to
INSTALLTED_APPS - gitkeep the templates/static folders created
- Make modifications to
frontendsub-project:
- in frontend/config/env.js — replace:
WDS_SOCKET_PORT: process.env.WDS_SOCKET_PORT,
by
WDS_SOCKET_PORT: 3000,
This will make React project's built-in websocket to the right port — where the React's server is and not e.g. 8000.
- In
frontend/scripts/start.jscomment outopenBrowsercommand. Before:
openBrowser(urls.localUrlForBrowser);
after:
//openBrowser(urls.localUrlForBrowser);
which doesn't open a browser at port 3000, 'cause we don't want direct output
of React's dev server (it will be got by Django instead).
- make the following modifications to
frontend/scripts/build.jsfile (to make build process also integrate with Django):- Add to the beginning:
const rimraf = require('rimraf');
const mkdirp = require('mkdirp');
- and also, install that modules (inside your
frontendfolder):
yarn add -D rimraf mkdirp
- before the first
.catch(...)statement in the file, prepend the following extra step:
.then(function () {
const filename = __dirname + '/../build/asset-manifest.json';
const chunks = {};
JSON.parse(fs.readFileSync(filename)).entrypoints.map(e => {
let ext = e.split('.');
ext = ext[ext.length - 1];
if (!chunks[ext]) chunks[ext] = [];
chunks[ext].push(e.replace('static/', '/static/react/'));
});
const appBase = __dirname + '/../../main/';
const templates = {
css: url => `<link rel="stylesheet" type="text/css" href="${url}" />`,
js: url => `<script type="text/javascript" src="${url}"></script>`,
}
for (let [k, v] of Object.entries(templates)) {
const html = chunks[k]?.map(v).join('');
const fileDir = `${appBase}templates/react/`;
mkdirp.sync(fileDir);
fs.writeFileSync(`${fileDir}bundle_${k}.html`, html);
}
const srcDir = __dirname + '/../build/static/';
const destDir = appBase + 'static/react/';
console.log(`will remove dir ${destDir}`);
rimraf.sync(destDir);
fs.copySync(srcDir, destDir, { overwrite: true }, function (err) {
if (err) {
console.error(err);
} else {
console.log(chalk.green("copy assets to build: success!"));
}
});
})
and check that the path __dirname + '/../../main/ (the appBase) points exactly to where your
location for auto-generated (during the build) templates and static files is.
This example is given for storing the files inside the folders of an app called main .
- Finally, in
frontend/config/webpack.config.jsreplace two occurrences ofstatic/media/byreact-static/media/:
assetModuleFilename: 'static/media/[name].[hash][ext]',
to
assetModuleFilename: 'react-static/media/[name].[hash][ext]',
and
name: 'static/media/[name].[hash].[ext]',
to
name: 'react-static/media/[name].[hash].[ext]',
to give specifically included static files, such as included images their own directory
('cause static may be already taken by Django).
- gitignore the auto-generated folders of yours:
main/templates/react/**
main/static/react/**
- Add files and commit — now you should have ready-to-go setup for developing and deploying Django + React project on a single port!
Development
In root folder:
export FRONTEND_DEV_MODE=1
python manage.py runserver
In frontend/ folder:
yarn start
Production
- Build frontend and collect static
cd frontend/
yarn build
cd ..
python manage.py collectstatic
- Deploy as normal (according to Django docs)
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file logicore-django-react-1.0.0.dev23.tar.gz.
File metadata
- Download URL: logicore-django-react-1.0.0.dev23.tar.gz
- Upload date:
- Size: 11.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.1 CPython/3.9.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6a314924f049813fc9b1460a3da2ff68f1bb087760b26b0c83eda4735679ec6f
|
|
| MD5 |
ea48ad4c1194b2b90ee222ae5fe3f0b7
|
|
| BLAKE2b-256 |
2ec2aece04e32404e33c018c9449fb68796b7b60602c9437dfc8e9fe6ef36c80
|
File details
Details for the file logicore_django_react-1.0.0.dev23-py3-none-any.whl.
File metadata
- Download URL: logicore_django_react-1.0.0.dev23-py3-none-any.whl
- Upload date:
- Size: 10.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.1 CPython/3.9.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
acb359912a63e7ff68f1f73bf3791572514ce514e1459bc2e9ecdcdbb38a3214
|
|
| MD5 |
f072187160663a38d55500da5e157fa8
|
|
| BLAKE2b-256 |
2d03424eea4bcfc5d11778dfa44f5d5be9417b9c8f954a8c643bba835bd13e2e
|