2

I'm working on tying my react(16.6.3) and Django(2.0) apps together. Right now I'm just working to get the dev server working and will focus on production later. I've been following a handful of guides on this process, but they're all a little different (and most seem outdated) and I haven't been able to find the right combination to get this working. My ultimate goal is that I'd like to be able to run the dev servers from 1 terminal window.

I'm using react-app-rewired because I'd like to not have to eject. My understanding is that it's more desirable to not eject rather than have to manually configure all of the Webpack configs. This may especially be true for me as I'm still learning react/webpack.

Its my understanding that once this is configured I just need to run the Django server and it should display my app. I'm not running collectstatic or any npm start or build commands.

Here's what I have configured:

base.py

...    
STATICFILES_DIRS = [
        # os.path.join(os.path.join(BASE_DIR, 'frontend'), 'build', 'static')
        os.path.join(BASE_DIR, "frontend", "build", "static"),
    ]
...

local.py

...
WEBPACK_LOADER = {
    "DEFAULT": {
        "CACHE": not DEBUG,
        "BUNDLE_DIR_NAME": "frontend/build/static/",  # must end with slash
        "STATS_FILE": os.path.join(BASE_DIR, "frontend", "build", "webpack-stats.json"),
    }
}
...

config-overrides.js

var BundleTracker = require('webpack-bundle-tracker');

module.exports = {
  webpack: (config, env) => {

    config.plugins.push(
      new BundleTracker({
        path: __dirname,
        filename: './build/webpack-stats.json'
      }),
    );

    return config;
  },
};

main.html

{ % load render_bundle from webpack_loader % }

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width" />
    <title>Django + React CRUD</title>
  </head>
  <body>
    <div id="root">
     This is where React will be mounted
    </div>
    { % render_bundle 'main' % }
  </body>
</html>

urls.py

from django.contrib import admin
from django.urls import path, include
from django.views.generic import TemplateView

urlpatterns = [
    path('admin/', admin.site.urls),
    path(r'', include('api.urls')),
    path(r'', TemplateView.as_view(template_name="main.html"))
]

With this configuration, and the Django server running, when I navigate to localhost:8000 all I see is a basic page:

enter image description here

Project Structure:

.
├── api
│   ├── __init__.py
│   ├── __pycache__
│   ├── admin.py
│   ├── apps.py
│   ├── migrations
│   ├── models.py
│   ├── serializers.py
│   ├── tests.py
│   ├── urls.py
│   └── views.py
├── financeApp
│   ├── __init__.py
│   ├── __pycache__
│   └── templates
├── build
│   └── webpack-stats.json
├── config
│   ├── __init__.py
│   ├── __pycache__
│   ├── settings
│   ├── urls.py
│   └── wsgi.py
├── database20181022.json
├── db.sqlite3
├── docker-compose-dev.yml
├── docker-compose.yml
├── docker_compose
│   ├── django
│   ├── nginx
│   ├── node
│   └── postgres
├── frontend
│   ├── README.md
│   ├── build
│   ├── config-overrides.js
│   ├── node_modules
│   ├── package-lock.json
│   ├── package.json
│   ├── package0.json
│   ├── public
│   └── src
├── manage.py
├── requirements
│   ├── base.txt
│   ├── local.txt
│   └── production.txt
├── static
│   ├── builds
│   ├── builds-development
│   └── js
├── templates
    └── main.html
brewcrazy
  • 623
  • 13
  • 30

2 Answers2

1

Django will not know what to serve. You need to build the app and then serve the built app with django as static.

Alternatively, while developing, serve the react app using npm start run, and Django separately with python manage.py runserver. Not sure what interdependencies you have between the two systems, but you should be able to dynamically specify the routing between npm/django based on the port number.

For production, serving of the assets should be done with a dedicated webserver (eg. Nginx) and routing established so that Nginx acts as a reverse proxy for routing to Django endpoints (e.g. an API).


With your current approach, this line below is trying to get Django to render the html file using Django templating, rather than react templating so you are getting the wrong output.

TemplateView.as_view(template_name="main.html")

You must either build the source so that these templates are resolved by react, or serve the react code through npm.

While it is possible to serve through django, but it is much more straightforward to serve react and django separately. A benefit of this way is that you have decoupled the front end (react) from the back end (django) and if you make changes to either, you only have to restart that service (front or back end)

Stuart Buckingham
  • 1,574
  • 16
  • 25
  • So I would need to run `npm run build` every time I make a change while doing development in order for Django to pick up the changes? – brewcrazy Jan 17 '19 at 19:29
  • I should add that my understanding of using `django-webpack-loader` and `webpack-bundle-tracker` was that hot reloading would work so I wouldn't have to take manual steps. Here's one of the guides that I've been following which mentions this: https://www.techiediaries.com/django-react-rest/ – brewcrazy Jan 17 '19 at 20:10
  • Absolutely. I just skimmed through the tutorial, and it looks like they are serving the react front end using npm (`npm run start`) and django is running the api separately. This is a very common setup and means that you can hot reload the code in react. Although it is possible to serve the react assets through django, the way they do it is fine. – Stuart Buckingham Jan 17 '19 at 22:02
  • My goal was to not have to have 2 separate terminal windows open to do my development. 1 for react and 1 for Django. Sounds like you're saying this isn't possible. – brewcrazy Jan 17 '19 at 22:04
  • @brewcrazy please mark as answered and upvote if this helped. – Stuart Buckingham Jan 25 '19 at 21:30
  • Unfortunately, this wasn't helpful. Unless I'm mistaken, you haven't answered the original question. I'm still looking for help on having Django load the React app using the technologies indicated in the original post. My understanding of your answer above is that you've proposed an alternate approach to working with Django/React. While I understand the argument for your approach, I'd like to stick with mine. – brewcrazy Jan 25 '19 at 21:35
0

Actually this is a syntax-related issue, the Django tags syntax looks like {% tag %} instead of { % tag % } (no space between the curly bracket and percentage sign).

For more information, please refer to the Django template language.

MrPromethee
  • 721
  • 9
  • 18
sjakur
  • 26
  • 1
  • 2