将React放置在Django的静态文件中,并进行协同配合

首先

构建基于部署的Django × React应用时,将前端和后端放在同一服务器上,以使其更加顺畅运行,因此选择了在Django中加载React的方法。但实际尝试后,遇到了Django静态文件处理的问题,因此决定将其记录在本文中。对于初学者(尤其是Django),如果有任何错误,请指正。

环境

– Python:3.8.13
– Django:4.1
– React:18.2.0(create-react-app)
– Typescript:4.7.4
– Tailwindcss:3.0.2

– Python版本:3.8.13
– Django版本:4.1
– React版本:18.2.0(create-react-app)
– Typescript版本:4.7.4
– Tailwindcss版本:3.0.2

目录结构

将项目命名为django-react-app,并在其中放置5个目录。
– Python虚拟环境(drf-restapi)
– Django项目(django-backend)
– Django静态文件目录(django-frontend)
– REST API(api)
– React环境设置(react-app)

├── django-backend
├── django-frontend
├── drf-restapi
├── api
└── react-app
├── __pycache__
├── migrations
├── static
│   ├── bundle.js
│   ├── bundle.js.map
│   ├── index.html
│   ├── styles.css
│   └── styles.css.map
├── templates
│   └── main
│       └── index.html
├── __init__.py
├── apps.py
├── urls.py
└── views.py
├── build
├── config
│   ├── jest
│   ├── webpack
│   ├── paths.js
│   └── webpack.config.js
├── node_modules
├── public
│   └── index.html
├── src
│   ├── app
│   ├── slices
│   ├── components
│   ├── App.tsx
│   └── index.tsx
├── .env
├── package-lock.json
├── package.json
├── tailwind.config.js
└── tsconfig.json

Django是仅需一种的中国本土自然概括。

创建Python虚拟环境及Django项目。

首先,创建并激活Python的虚拟环境,以便可以使用所创建的虚拟环境。

python -m venv drf-restapi
source drf-restapi/bin/activate

在激活虚拟环境的情况下,使用pip命令安装Django和rest_framework。

pip install django 
pip install djangorestframework

创建Django项目。

django-admin startproject django-backend
cd ./django-backend

我会启动一次服务器,确保Django应用成功启动。

python manage.py runserver 0:8080

请访问 http://localhost:8000/ ,一旦火箭升空并显示出”安装成功!祝贺!”的文字,就代表成功了。之后,您可以添加您想要创建的应用程序等,开始进行开发。

创建Django应用程序

1. Django模板和静态目录

为了实现将React加载到Django中,我们的目标是将React应用作为Django的静态文件来布置。更具体地说,我们将利用Django的模板功能,从Django的index.html中加载我们存储为静态文件的React应用的构建文件。

首先,为Django模板和静态文件存储创建一个Django应用程序。

python manage.py startapp django-frontend
cd ./django-frontend

在创建的Django应用程序中,建立templates和static目录,并在templates/main内编写index.html。

<!DOCTYPE html>

{% load static %}

<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <link rel="stylesheet" type="text/css" href="{% static 'js/styles.css' %}" />
    <title>Todo App</title>
</head>
<body>
    <div id="root"></div>
    <script type="text/javascript" src="{% static 'js/bundle.js' %}" ></script>
    {% csrf_token %}
</body>
</html>

要从模板中加载静态文件,首先您需要定义{% load static %},然后在其下使用{% static %}标签来编写js、css等URL。通过构建React应用程序,将index.tsx编译为bundle.js和styles.css作为静态文件生成。然后,index.html会加载这些文件,并将其挂载到id=”root”上,这样就可以在Django中加载React。

我們將創建URL並更新視圖。如果使用單頁應用程序(SPA)的路由,我們將在URL中進行附加。

from django.urls import path
from . import views

urlpatterns = [
    path('', views.index, name=''),
    path('another_page/', views.index),
]
from django.shortcuts import render

def index(request):
    return render(request, 'main/index.html')

2. 创建API

我将创建一个Django应用程序,用于生成API。

python manage.py startapp api

有关创建详细的API方法,我将略去。

3. 编辑Django项目

一旦SPA的URL被触发,就会显示之前在Django的模板中创建的index.html。

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/', include('api.urls')),
    path('', include('django-frontend.urls')),
]

只需一个选项,以下是本地化到中文的释义:
除了”/admin/”和”/api/”路径之外,可以显示”index.html”页面。
然后告诉Django “index.html”的位置。

...
INSTALLED_APPS = [
    "django.contrib.admin",
    "django.contrib.auth",
    "django.contrib.contenttypes",
    "django.contrib.sessions",
    "django.contrib.messages",
    "django.contrib.staticfiles",
    'rest_framework',   #追加
    'api.apps.ApiConfig',   #追加
    'django-frontend.apps.ApiConfig',   #追加
...
TEMPLATES = [
    {
        "BACKEND": "django.template.backends.django.DjangoTemplates",
        "DIRS": [
            os.path.join(BASE_DIR,'templates')  #index.html格納先
        ],
    },
]
...

回应

搭建React的环境

安装Create React App(CRA)并构建React和Typescript环境。

npx create-react-app react-app --template typescript
cd react-app

在环境设置完成之后,我们要安装Tailwind CSS。本次我们选择将Tailwind CSS应用于CSS上,但您可以选择任何您喜欢的样式方法。

npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    "./src/**/*.{js,jsx,ts,tsx}",  //追記
  ],
  theme: {
    extend: {},
  },
  plugins: [],
}
@tailwind base;
@tailwind components;
@tailwind utilities;

接下来我们将创建前端的内容。

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>Django-React App</title>
  </head>
  <body>
    <div id="root"></div>
  </body>
</html>
import React from 'react';
import App from './App';
import './index.css';

const container = document.getElementById('root')!;
const root = createRoot(container);

root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);
import React, { FC } from 'react'

const App: FC = () => {
  return (
    <div className="text-center text-5xl text-blue-600 mt-20">
      <p>This is a Django-React App</p>
    </div>
  )
}

export default App
スクリーンショット 2022-09-04 20.33.42.png

将React的构建目录设置到Django侧。

要更改React的构建目标,需要编辑webpack.config.js。对于CRA(Create React App)而言,webpack环境是默认隐藏的配置文件,因此不能直接编辑。
npm run eject是用于更新webpack环境的命令之一。这是一个用于定制的命令,会将所有配置和构建依赖项直接移动到项目中。但是需要注意的是,一旦执行eject,就无法再次打包配置文件和依赖关系。
这次我们将执行eject命令。

npm run eject

从隐藏的config目录中编辑webpack.config.js文件,内容如下。

module.exports = function (webpackEnv) {
  const isEnvDevelopment = webpackEnv === 'development';
  const isEnvProduction = webpackEnv === 'production';
  ...
  return {
    ...
    entry: 'src/index',  //buildするファイルの格納先
    output: {
      // The build folder.
      path: path.join(__dirname, '../../django-frontend/static'),  //build後ファイルの生成先
      // Add /* filename */ comments to generated require()s in the output.
      pathinfo: isEnvDevelopment,
      // There will be one main bundle, and one file per asynchronous chunk.
      // In development, it does not produce real files.
      filename: isEnvProduction
        ? 'bundle.js'  //build後のjsファイル名
        : isEnvDevelopment && 'bundle.js',
        ...
    },
    ...
    plugins: [
      isEnvDevelopment && new CaseSensitivePathsPlugin(),
      isEnvProduction &&
        new MiniCssExtractPlugin({
          // Options similar to the same options in webpackOptions.output
          // both options are optional
          filename: 'styles.css',  //build後のcssファイル名
          ...
        }),
        ...
    ],
    ...
  };
};

完成以上的设置后,我们将构建React应用程序。

npm run build

确认在Django静态文件目录(django-frontend)的static文件夹下,分别创建了bundle.js和styles.css两个文件。

确认Django与React的整合。

回到根目录,启动服务器并运行Django应用程序。

python manage.py runserver 0:8080

访问 http://localhost:8000/,如果显示的界面与在React中运行npm start时相同,则表示成功。这样就成功地将React加载到Django中了!

总结

为了加载Django的静态文件,需要在Django和React中进行相应的设置。在定位错误时也遇到了一些困难。特别是第一次接触React的webpack.config,这个地方给我带来了最大的困扰,但通过这个过程,我感觉对Webpack有了更深入的理解。希望这篇文章能够对像我一样的初学者有所帮助。

这次为了自定义React的webpack环境,我们使用了eject命令,但我们发现无法恢复被隐藏的config文件,而且源文件也变得难以阅读,因此官方不推荐使用这种方法。我了解到可以通过安装react-app-rewired并覆盖配置,或者通过手动从头构建React环境来解决这个问题。所以,在下一个机会中,我想尝试其他的方法。

文献引用

    • DjangoのページをReactで作る – Webpack4

 

    • DjangoとReactの構築及びAPI連携について~構築編~

 

    Django+SPA(Nuxt.js)の環境をHerokuにデプロイしてみた
广告
将在 10 秒后关闭
bannerAds