关于Django和React的建立和API协调~建立部分~
这篇文章是“AP通信2020年圣诞日历”的第13天的参赛作品。作为今年所做事情的总结,我将在此记录。
简要总结
本文的目的是介紹一種構建Web應用程序的方式,即使用Django作為後端,使用React作為前端。同時,為了實現從React中對Django數據庫的查詢和更新,我們還將使用Django REST框架對數據庫進行API化。最終的成品預期如下所示。

在本次中篇,我跳过了Django与Apache的协作。您可以通过在运行服务器上运行Django来实现与正在运行的Apache的集成。参考资料:Django与Apache的协作。
因为变得比我想象中的长,所以关于使用React进行API数据更新的问题,我将在另一篇文章中讨论。
环境
在一台服务器上安装Django和React。数据库使用Django的默认选项(SQLite3),但也可以使用MySQL等其他选项。本次环境如下:
・CentOS7
・Python3.7
・Django3
・Node.js14
Django – Django
立即开始努力。这次我将在刚更新的全新Centos7上进行工作。
首先安装小工具。
[root@localhost ~]# yum install -y gcc zlib-devel libffi-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gdbm-devel libuuid-devel xz-devel wget
安装Python3
接下来安装Python3.7。
在使用Django3.0时,只要Python的版本是3.6或更高就没有问题,我们将从源代码进行安装。
[root@localhost ~]# wget https://www.python.org/ftp/python/3.7.9/Python-3.7.9.tgz
[root@localhost ~]#tar xzf Python-3.7.9.tgz
[root@localhost ~]#cd Python-3.7.9
[root@localhost Python-3.7.9]#./configure --enable-optimizations
[root@localhost Python-3.7.9]#make altinstall
~~~~
Successfully installed pip-20.1.1 setuptools-47.1.0
[root@localhost Python-3.7.9]# python3.7 -V
Python 3.7.9
##ここでいちいちpython3.7と打つのが面倒なのでpython3で起動するようシンボリックリンクを設定する。
[root@localhost Python-3.7.9]# which python3.7
/usr/local/bin/python3.7
[root@localhost Python-3.7.9]# ln -s /usr/local/bin/python3.7 /usr/bin/python3
[root@localhost Python-3.7.9]# python3 --version
Python 3.7.9
##次にpipをインストールする。yumなどで入れると自動的に入るが、ソースからインストールすると入らない。
[root@localhost Python-3.7.9]# curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
[root@localhost Python-3.7.9]# python3 get-pip.py
[root@localhost Python-3.7.9]# pip3 -V
pip 20.3.1 from /usr/local/lib/python3.7/site-packages/pip (python 3.7)
安装Django和rest_framework
[root@localhost Python-3.7.9]# pip3 install Django
[root@localhost Python-3.7.9]# pip3 install djangorestframework
SQLite3的最新升级
下一步是将SQLite3更新到最新版本。原因是默认情况下,版本较低会在启动时引发错误。您可以在“https://www.sqlite.org/download.html”上确认当前的最新版本。
[root@localhost ~]# wget https://www.sqlite.org/2020/sqlite-autoconf-3340000.tar.gz
[root@localhost ~]# tar zxvf sqlite-autoconf-3340000.tar.gz
[root@localhost ~]# cd sqlite-autoconf-3340000
[root@localhost sqlite-autoconf-3340000]# ./configure --prefix=/usr/local
[root@localhost sqlite-autoconf-3340000]# make
[root@localhost sqlite-autoconf-3340000]# make install
[root@localhost sqlite-autoconf-3340000]# cd ..
[root@localhost ~]# find / -name sqlite3
/root/Python-3.7.9/Doc/includes/sqlite3
/root/Python-3.7.9/Lib/sqlite3
/root/sqlite-autoconf-3340000/sqlite3
/usr/bin/sqlite3
/usr/lib64/python2.7/sqlite3
/usr/local/bin/sqlite3
/usr/local/lib/python3.7/site-packages/django/db/backends/sqlite3
/usr/local/lib/python3.7/sqlite3
##バージョンを確認する。
[root@localhost ~]# /usr/local/bin/sqlite3 --version
3.34.0 2020-12-01 16:14:00 a26b6597e3ae272231b96f9982c3bcc17ddec2f2b6eb4df06a224b91089fed5b
[root@localhost ~]# /usr/bin/sqlite3 --version
3.7.17 2013-05-20 00:56:22 118a3b35693b134d56ebd780123b7fd6f1497668
[root@localhost ~]# sqlite3 --version
3.34.0 2020-12-01 16:14:00 a26b6597e3ae272231b96f9982c3bcc17ddec2f2b6eb4df06a224b91089fed5b
[root@localhost ~]# mv /usr/bin/sqlite3 /usr/bin/sqlite3_old
[root@localhost ~]# ln -s /usr/local/bin/sqlite3 /usr/bin/sqlite3
[root@localhost ~]# echo 'export LD_LIBRARY_PATH="/usr/local/lib"' >> ~/.bashrc
[root@localhost ~]# source ~/.bashrc
[root@localhost ~]# python3
Python 3.7.9 (default, Dec 7 2020, 23:13:43)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-44)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import sqlite3
>>> sqlite3.sqlite_version
'3.34.0'
>>> exit()
创建Django项目
接下来,创建项目。
[root@localhost ~]# mkdir /home/django
[root@localhost ~]# cd /home/django/
[root@localhost django]# django-admin startproject django_react
[root@localhost django]# ls
django_react
##起動確認を行う。
[root@localhost ~]# cd django_react
[root@localhost django_react]# ls
django_react manage.py
[root@localhost django_react]# python3 manage.py migrate
~~~~
Applying sessions.0001_initial... OK
[root@localhost django_react]# python3 manage.py runserver
访问 http://localhost:8000/ 确认 Django 启动页面显示。

我也会创建应用程序。顺便提一下,从这里开始,我会进行文件更新,所以个人建议准备好可以通过Remote连接使用vscode等工具会比较方便。不用每次都在服务器上用vi去更新文件。我是使用vscode的Remote SSH,在下面的方式下进行工作。

[root@localhost django_react]# python3 manage.py startapp react_app
[root@localhost django_react]# python3 manage.py startapp api
##apiは後ほどAPIを作成するときに使用する。
修改settings.py文件。
~~~~
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'react_app', #追加
]
我会确认所创建的应用程序是否正常运行。
我会持续更新react_app文件夹下的文件。
from django.shortcuts import render
from django.http import HttpResponse
def index(request):
return HttpResponse("Hello, world. You're at the react_app index.")
##urls.pyはデフォルトでは作成されていないので作成すること。
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name='index'),
]
更新django_react的urls。
from django.contrib import admin
from django.urls import include,path
urlpatterns = [
path('admin/', admin.site.urls),
path('react_app/', include('react_app.urls')),
]
运行`runserver`命令,并访问http://localhost:8000/react_app/,确保屏幕显示正常。

Django的基本设置已经完成。
Django REST框架
增加设定
接下来进行API的准备工作。
~~~~
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'react_app', #追加
'rest_framework', # 追加
'api.apps.ApiConfig', # 追加
]
~~~~
# Setting permission
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.AllowAny',
]
}
数据库准备
准备将数据库转化为API。
由于这次只需要进行操作确认,所以我们随意创建一个用户表,并在其中插入一些测试数据。
from django.db import models
# Create your models here.
class User_Models(models.Model):
class Meta:
db_table = 'User'
user_id = models.CharField(
verbose_name='userid',
blank=True,
null=True,
max_length=225,
default='',
)
user_name = models.CharField(
verbose_name='username',
blank=True,
null=True,
max_length=225,
default='',
)
user_age = models.CharField(
verbose_name='userage',
blank=True,
null=True,
max_length=225,
default='',
)
user_email = models.CharField(
verbose_name='useremail',
blank=True,
null=True,
max_length=225,
default='',
)
def __str__(self):
return self.user_id
[root@localhost django_react]# python3 manage.py makemigrations
Migrations for 'react_app':
react_app/migrations/0001_initial.py
- Create model User_Models
[root@localhost django_react]# python3 manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, contenttypes, react_app, sessions
Running migrations:
Applying react_app.0001_initial... OK
[root@localhost django_react]#
在管理界面中进行数据输入,因此需要在admin.py文件中进行记录。
from django.contrib import admin
from react_app.models import User_Models
admin.site.register(User_Models)
创建一个超级用户以便登录管理网站。
[root@localhost django_react]# python3 manage.py createsuperuser
创建后运行服务器,并访问http://localhost:8000/admin,在先前创建的超级用户账户登录。


在投入适当的测试数据。
路由和序列化设置
接下来需要进行路由配置和数据库的序列化。
在api应用文件夹下创建serializers.py文件,并按照以下方式进行编写。
from rest_framework import serializers
from react_app.models import User_Models
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User_Models
fields = ('user_id', 'user_name', 'user_age','user_email')
在views.py中,按以下方式进行描述。
from rest_framework import viewsets, routers
from react_app.models import User_Models
from .serializers import UserSerializer
class UserApi(viewsets.ModelViewSet):
queryset = User_Models.objects.all()
serializer_class = UserSerializer
def get_queryset(self):
queryset = User_Models.objects.all()
L_id = self.request.query_params.get('id')
if L_id:
queryset = queryset.filter(user_id=L_id)
return queryset
router = routers.DefaultRouter()
router.register(r'user', UserApi)
在这里稍作修改。具体来说,我让它可以通过URL查询进行搜索。当通过查询接收到ID时,我让它在数据库中进行ID搜索。实际操作稍后确认。
进行路由设置。
在项目的 URL 中按照以下方式添加。
from django.contrib import admin
from django.urls import include,path
from api import views
urlpatterns = [
path('admin/', admin.site.urls),
path('react_app/', include('react_app.urls')),
path('api/', include(views.router.urls)),
]
API准备就绪后,请运行服务器,并访问http://localhost:8000/api/user。若显示如下内容,则表示成功。

试着给URL添加查询并进行搜索。
尝试访问http://localhost:8000/api/user/?id=1001。

可以确认通过ID可以正确地进行搜索。
回应
安装
需要使用React,需要安装一个以上的Node.js版本。默认的版本可能较低,所以请参考https://github.com/nodesource/distributions/blob/master/README.md,在此安装最新版本的Node.js。本次安装选择版本14。
[root@localhost ~]# curl -sL https://rpm.nodesource.com/setup_14.x | bash -
[root@localhost ~]# yum -y install nodejs
[root@localhost ~]# node -v
v14.15.1
[root@localhost ~]# npm -v
6.14.8
##npm経由でyarnをインストールする
[root@localhost ~]# npm install -g yarn
[root@localhost ~]# yarn -v
1.22.10
接下来,使用 create-react-app 命令来创建一个 React 应用程序。
可以选择任何地方,但我选择在 /home/django 目录下创建。
[root@localhost django]# pwd
/home/django
[root@localhost django]# yarn create react-app django_front
~~~~
Happy hacking!
Done in 50.89s.
[root@localhost django]#
##動作確認を行う。
[root@localhost django]# cd django_front/
[root@localhost django_front]# yarn start
只需要一种选择,以下是对上述内容的中文本地化释义:
若能访问http://localhost:3000并显示以下页面,则说明初始设置已完成。

React和Django的整合
到目前为止,Django和React分别在不同的环境中能够运行。
本文将演示如何将在React中创建的内容显示在Django中,就像最初的示意图中所示。在React中进行界面开发时,我们可以使用”yarn start”命令来实时查看构建的效果,并在构建完成后将其以静态文件的形式放置在Django的相应位置。
首先,在Django应用程序的一侧创建index.html文件。由于应用程序的文件夹越来越多了,所以要注意路径。
<!DOCTYPE html>
{% load static %}
<html lang="en">
<head>
<meta charset="utf-8">
<title>React</title>
</head>
<body>
<div id="app"></div>
<script type="text/javascript" src="{% static 'js/bundle.js' %}" ></script>
</body>
</html>
顺便提一下,在这个阶段访问http://localhost:8000/react_app/,没有任何显示。这是因为当前没有加载任何js文件。当在React中执行构建操作时,会自动放置js文件。
在React端进行构建准备。如果使用默认的yarn build命令进行构建,将会创建大量的文件。为了将构建后的文件合并成一个文件,安装并使用webpack。以下文章提供了关于webpack的详细信息。
注意:由于中文字符限制,无法提供完整的原文翻译,请以以上翻译内容为准。
参考资料:了解Webpack和Babel的基础知识。
安装所需的模块。
[root@localhost django_front]# yarn add @babel/preset-react babel-loader --dev
创建webpack.config.js。重要的是entry和output。将来如果要构建更多的文件,还需要适时添加module的配置。
const path = require('path');
module.exports = {
mode: 'development',
entry: './src/index.js', //buildするファイル
output: {
filename: 'bundle.js', //build後のファイル名
path: path.join(__dirname, '../django_react/react_app/static/js') //buildファイルが作成される場所
},
module: {
rules: [
{
test: /\.js[x]?$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: [
'@babel/preset-env',
'@babel/preset-react'
],
plugins: ['@babel/plugin-syntax-jsx']
}
}
}
]
},
resolve: {
extensions: ['.js', '.jsx', '.json']
}
};
准备用React构建屏幕。
import React from "react";
const App = () => {
return (
<div>
<p>React here!</p>
</div>
);
};
export default App;
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
ReactDOM.render(<App />, document.getElementById("app"));
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>React App</title>
</head>
<body>
<div id="app"></div>
</body>
</html>
在这里创建一个.env文件,并按照下面的内容进行记录,然后运行yarn start。
SKIP_PREFLIGHT_CHECK=true

如果出现这个画面就可以了。那就尝试构建吧。
[root@localhost django_front]# yarn webpack
然后会在 “/home/django/django_react/react_app/static/js” 目录下创建js文件。(同时也会自动创建文件夹)
如果访问 http://localhost:8000/react_app/,并且出现与刚才的 port3000 相同的界面,那就表示成功。
.env是什么意思?
刚刚创建了.env文件,其意义在于在yarn start时跳过包之间的依赖关系检查。原因是babel-loader的版本升级后,如果不创建.env文件并执行yarn start,则会触发依赖检查并导致无法启动。这次为了强行跳过依赖检查。但在之后的构建过程中,我们不确定会有什么影响,所以这是一个应该尽早解决的问题。(本文中将跳过依赖检查)
概述
在本文中,我们搭建了Django和React的环境,并且已经成功实现了在Django中显示React应用程序的功能。
实际上,对于环境搭建部分,我们本来想通过使用Docker和Ansible进行自动化来完成,但是由于时间紧迫而放弃了。对于这一点,我们打算另外来做。
接下来,我们将进行设置,以便从React通过API访问和更新Django的数据库。