环境准备
react项目的环境准备和配置参考(后面会需要修改react项目的一些配置,建议先了解):
https://blog.csdn.net/sysukehan/article/details/104872248
可以直接使用的react项目地址:
https://github.com/sysu-kehan/first-react-and-webpack-project.git
使用Django需要python环境,pycharm IDE。
python下载安装:https://www.python.org/downloads/
pycharm社区版下载安装:
https://www.jetbrains.com/pycharm/download/#section=windows
安装Django
python安装完成后,在命令行中输入:
pip install Django
完成安装后需要进一步校验是否安装成功。打开命令行,输入“python”后按回车键,进入python交互解释器,在交互解释器下输入校验代码:
>>> import django
>>> django.__version__
能查询到版本说明安装成功。
创建Django项目
在命令行中执行
django-admin startproject firstReactAndDjangoProject
创建项目成功后,进入目录,在命令行执行:
python manage.py runserver 80
在浏览器窗口打开http://127.0.0.1:80/,可以看到Django项目的默认html界面。
用pycharm启动项目
用pycharm打开项目,点击上方的Add Configurations...
点击左上角的+号,选择python。在右边的配置中,Script path用右边的选择按钮选择项目根目录下的manage.py,parameters中手动填入runserver 80,点击OK保存。
之后刚刚右上角会出现Add Configurations...的位置会出现manage,绿色三角箭头也亮起来了。
在开始运行之前把所有的命令行窗口关闭,避免刚刚命令行启动的进程占用端口导致启动失败。点击绿色箭头启动项目,在pycharm中可以看到提示是一样的,项目也启动了。
替换html页面为react生成的html页面
在项目根目录下启动命令行,执行:
python manage.py startapp index
在项目文件夹下有一个和根目录同名的文件夹,是创建Django项目的时候一起创建的,里面包含了一些配置文件。其中urls.py文件用于查找该URL是属于哪个App,然后再从App的urls.py找到具体的URL信息。在其中添加加粗部分内容:
from django.contrib import admin
from django.urls import path,include
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('index.urls'))
]
from django.urls import path,include:导入URL编写模块
urlpatterns:整个项目的URL集合,每个元素代表一条URL信息。
path(‘’, include(‘index.urls’)):URL为空,代表为网站的域名,即127.0.0.1:80,通常是网站的首页;include将该URL分发给index的urls.py处理。
进入index文件夹,新建一个urls.py文件,内容如下:
from django.urls import path
from . import views
urlpatterns = [
path('', views.index)
]
上述代码导入了同一目录下的views.py文件,该文件用于编写视图函数,处理URL请求信息并返回网页内容给用户。
编辑views.py文件,添加如下内容:
def index(request):
return render(request, 'index.html')
index函数必须设置参数request,该参数代表当前用户的请求对象,该对象包含用户名、请求内容和请求方式等信息,视图函数执行完成后必须使用return将处理结果返回,否则程序会抛出异常。
index.html就是要显示的首页,也就是在react项目中编译出来的index.html。把配置好的react项目放到根目录下,重命名react项目文件夹名为webproject,然后配置views.py到这个目录中去寻找index.html。
存放配置文件的目录下还有一个settings.py文件,设置了一些项目参数,有一个配置模板目录的参数DIRS,默认是[]。
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
修改为:
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'webproject/dist')],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
这样Django就会到webproject目录下的dist目录去寻找html文件了。BASE_DIR是项目根目录,在settings.py文件中已有定义:
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
启动项目后,发现html是空白的,浏览器控制台报错找不到资源,pycharm控制台报错找不到bundle.js。
在浏览器的Elements页签中可以看到这种情况下Django是以127.0.0.1/bundle.js方式去寻找bundle.js的。但是因为没有设置寻找静态资源的路径,所以找不到。
在settings.py中有一个参数STATIC_URL,默认值为/static/,意思是Django会到各个App目录下的static文件夹中去找静态资源,但是bundle.js并不在App里面(在这个实例中,也就是不在index/static文件夹里面),是在webproject/dist文件夹下,所以需要配置STATICFILES_DIRS属性。
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'webproject/dist')]
注意:
- STATIC_URL是必须配置的属性而且属性值不能为空。如果没有配置STATICFILES_DIRS,则STATIC_URL只能识别App里的static静态资源文件夹。
- STATICFILES_DIRS是可选配置属性,属性值为列表或元组格式,每个列表(元组)元素代表一个静态资源文件夹,这些文件夹可自行命名。
- 在浏览器上访问项目的静态资源时,无论项目的静态资源文件夹是如何命名的,在浏览器上,静态资源的上级目录必须为static,而static是STATIC_URL的属性值,因为STATIC_URL也是静态资源的起始URL。
因为在引用静态资源时上级目录必须为static,所以在html中引用js资源要在原有的资源前加上/static/,这样Django才能访问到指定的静态资源。这种情况下只能先在模板html文件中把js引用写死来规避了。修改webproject/src/index.html文件:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>first project</title>
</head>
<body>
<div id="root"></div>
<script type="text/javascript" src="/static/bundle.js"></script>
</body>
</html>
这样启动后就可以访问到正确的html页面,内容也可以正确加载了。
图片引用问题
html页面正确了,但是图片加载不出来,还是静态资源引用的问题。在webpack中,图片被打包成hash命名的资源然后在js中被引用:
function(e,t,n){"use strict";n.r(t);var r=n(0),l=n.n(r),i=n(4),o=n.n(i),a=(n(10),n.p+"5d5d9eefa31e5e13a6610d9fa7a283bb.svg");
这种引用方式在Django的框架下就不适用了,所以图片资源要打包到js中去,要改用url-loader来解析图片。
安装:
npm i url-loader -D
修改webpack.config.js的配置(把原先的file-loader替换为url-loader):
{
test: /\.(png|svg|jpg|gif)$/,
use: [
'url-loader'
]
},
然后重新编译,新的html页面图片可以正常加载了。
js引用问题
在前面的配置过程中,为了使Django能正确引用到js,把js的引用路径写死在模板html中,这其实已经违背了使用html-webpack-plugin插件的初衷。因此可以不使用这个插件,只生成js,然后在模板html写死引用js的方法,展示页面直接使用模板html而不是编译后的html。
在webpack.config.js中删除html-webpack-plugin和clean-webpack-plugin插件的使用(- 部分)。
在Django项目根目录创建static文件夹,在static文件夹中再创建js和html文件夹,把webpack的打包js输出路径指定到static/js目录下。同时把模板html放到static/html目录下。
调整Django项目settings.py的配置,使项目到static/js目录下寻找引用的js文件。
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static/html')]
调整Django项目settings.py的配置,使项目到static/js目录下寻找模板的html文件(加粗部分需要调整)。
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'static/html')],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
启动项目,运行正常。
项目地址
https://github.com/sysu-kehan/firstReactAndDjangoProject.git
参考资料
《玩转Django 2.0》黄永祥/著,清华大学出版社