将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
将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にデプロイしてみた