Bootstrap

从零开始创建react+Django项目

环境准备

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')]

注意:

  1. STATIC_URL是必须配置的属性而且属性值不能为空。如果没有配置STATICFILES_DIRS,则STATIC_URL只能识别App里的static静态资源文件夹。
  2. STATICFILES_DIRS是可选配置属性,属性值为列表或元组格式,每个列表(元组)元素代表一个静态资源文件夹,这些文件夹可自行命名。
  3. 在浏览器上访问项目的静态资源时,无论项目的静态资源文件夹是如何命名的,在浏览器上,静态资源的上级目录必须为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》黄永祥/著,清华大学出版社

 

;