如何让 Django 和 ReactJS 一起工作?

Posted

技术标签:

【中文标题】如何让 Django 和 ReactJS 一起工作?【英文标题】:How to get Django and ReactJS to work together? 【发布时间】:2017-06-11 13:06:28 【问题描述】:

Django 的新手,甚至 ReactJS 的新手。我一直在研究 AngularJS 和 ReactJS,但决定使用 ReactJS。尽管 AngularJS 拥有更多的市场份额,但它的受欢迎程度似乎已经超过了 AngularJS,而且据说 ReactJS 的普及速度更快。

抛开这些垃圾不谈,我开始学习 Udemy 课程,看了几个视频后,看看它与 Django 的集成情况似乎很重要。那是我刚启动并运行它就不可避免地碰壁的时候,那里有什么样的文档,所以我不会在几个小时和几个晚上旋转我的***。

真的没有任何全面的教程,或pip 包,我遇到了。我遇到的少数没有工作或已过时,例如pyreact

我的想法只是将 ReactJS 完全分开,但要考虑到我希望 ReactJS 组件呈现的类和 ID。在将单独的 ReactJS 组件编译为单个 ES5 文件后,只需导入该单个文件进入 Django 模板。

我认为当我从 Django 模型进行渲染时,这将很快崩溃,尽管 Django Rest Framework 听起来像是涉及到它。甚至还不足以了解 Redux 如何影响所有这些。

不管怎样,有谁知道他们使用 Django 和 ReactJS 的明确方法,他们愿意分享吗?

无论如何,AngularJS 和 Django 的文档和教程都很丰富,所以很容易就这样开始使用任何前端框架......这不是最好的理由。

【问题讨论】:

我也有类似的好奇心,并为 react+webpack+django 设置了一个 example 应用程序 - 该 repo 还链接到一些可能有用的相关工具和文章。 【参考方案1】:

我没有使用 Django 的经验,但是前端到后端、前端框架到框架的概念是一样的。

    React 会消耗你的 Django REST API。前端和后端没有以任何方式连接。 React 将向您的 REST API 发出 HTTP 请求,以获取和设置数据。 React 在 Webpack(模块捆绑器)和 Babel(转译器) 的帮助下,会将您的 javascript 打包并转译成单个或多个文件,这些文件将放置在入口 html 页面中。 学习 Webpack、Babel、Javascript 以及 React 和 Redux(一个状态容器)。我相信您不会使用 Django 模板,而是允许 React 呈现前端。 在渲染此页面时,React 将使用 API 来获取数据,以便 React 可以渲染它。您对 HTTP 请求、Javascript (ES6)、Promises、中间件和 React 的理解至关重要。

以下是我在网络上发现的一些应该帮助的东西(基于快速的 Google 搜索):

Django and React API Youtube tutorial Setting up Django with React(将失效链接替换为archive.org链接) 使用上面加粗的术语搜索其他资源。首先尝试“Django React Webpack”。

希望这会引导您朝着正确的方向前进!祝你好运!希望其他专门研究 Django 的人可以添加到我的回复中。

【讨论】:

我会查看 YouTube 教程。我之前确实看过这两个教程。尽管我密切关注第 1 条,但它并没有起作用。 (复制并粘贴了大部分代码)。那是在一个现有的项目上,但我会尝试一个新的。第 2 条使用了已弃用的软件包,并且最近没有更新。无论如何,阅读更多关于 AngularJS 和 Django 的信息,听起来 Django REST API 仍在使用。我想我正在寻找一个不添加该维度的解决方案,但听起来这是不可避免的。 好的,我通过删除过时的文章更新了我的答案。它已经超过 2 年了,所以它肯定需要被删除。编号的子弹有帮助吗?你在理解什么方面有困难? 在现有项目和全新项目上多次尝试第二个链接后,我至少让他们说话了。 % render_bundle 'main' % 行是错误的,应该是 % render_bundle "main" % 第二个链接失效了。请更新链接。 我会用这篇文章替换那个死掉的第二个链接,我关注了这个,它大部分都有效..medium.com/labcodes/configuring-django-with-react-4c599d1eae63【参考方案2】:

当我开始让 Django 和 React.js 一起工作时,我也感受到了你的痛苦。做了几个 Django 项目,我认为 React.js 非常适合 Django。但是,开始可能会令人生畏。我们站在巨人的肩膀上;)

这就是我的想法,所有这些都可以协同工作(大图,如果我错了,请有人纠正我)。

一侧(后端)的 Django 及其数据库(我更喜欢 Postgres) Django Rest-framework 提供与外界的接口(即移动应用和 React 等) 另一端(前端)的 Reactjs、Nodejs、Webpack、Redux(或者可能是 MobX?)

Django 和“前端”之间的通信是通过 Rest 框架完成的。确保您获得了对 Rest 框架的授权和权限。

我为这个场景找到了一个很好的锅炉模板,它开箱即用。只需按照自述文件https://github.com/scottwoodall/django-react-template 操作,完成后,您就可以运行一个非常漂亮的 Django Reactjs 项目。 这绝不是为了生产,而是作为一种让您深入了解事物如何连接和工作的方式!

我想建议的一个微小变化是: 请按照设置说明进行操作,但在进行第二步设置后端之前(此处为 Django https://github.com/scottwoodall/django-react-template/blob/master/backend/README.md),更改设置的要求文件。

您可以在 /backend/requirements/common.pip 的项目中找到该文件 用这个替换它的内容

appdirs==1.4.0
Django==1.10.5
django-autofixture==0.12.0
django-extensions==1.6.1
django-filter==1.0.1
djangorestframework==3.5.3
psycopg2==2.6.1

这将为您提供 Django 及其 Rest 框架的最新稳定版本。

希望对你有帮助。

【讨论】:

一年后,我切换到 VUE.js (vuejs.org)。我让它与 Django 模板一起工作,它将通过 Django Rest Framework 与数据库通信。它又快又轻(~20kb)【参考方案3】:

希望提供比这里的任何答案都更细致入微的答案,尤其是自从大约 4 年前最初提出这个问题以来,有些事情已经发生了变化,而且因为许多获得最高票数的答案声称您必须进行设置因为两个单独的应用程序并不准确。

您有两种主要的架构选择:

    使用create-react-app 和Django REST Framework 之类的完全解耦的客户端/服务器方法 一种混合架构,您可以在其中设置 React 构建管道(可能使用 webpack),然后将编译后的文件作为静态文件包含在 Django 模板中。

这些可能看起来像这样:

选项 1(客户端/服务器架构):

选项 2(混合架构):

这两者之间的决定将取决于您/您的团队的经验,以及您的 UI 的复杂性。如果您有丰富的 JS 经验,希望将前端/后端开发人员分开,或者希望将整个应用程序编写为 React 单页应用程序,那么第一个选项会很好。 .如果您更熟悉 Django 并且希望在应用的某些部分使用 React 的同时快速移动,则第二种选择通常更好。我发现它特别适合全栈独立开发者。

“Modern JavaScript for Django Developers”系列中还有很多信息,包括choosing your architecture、integrating your JS build into a Django project和building a single-page React app。

完全公开,我是该系列的作者。

【讨论】:

【参考方案4】:

正如其他人回答的那样,如果您正在创建一个新项目,您可以将前端和后端分开,并使用任何 django rest 插件为您的前端应用程序创建 rest api。这是在理想世界中。

如果您的项目已经使用了 django 模板,那么您必须在要加载应用程序的页面中加载您的 react dom 渲染。就我而言,我已经 django-pipeline 并且我刚刚添加了 browserify 扩展。 (https://github.com/j0hnsmith/django-pipeline-browserify)

与示例一样,我使用 django-pipeline 加载了应用程序:

PIPELINE = 
    # ...
    'javascript':
        'browserify': 
            'source_filenames' : (
                'js/entry-point.browserify.js',
            ),
            'output_filename': 'js/entry-point.js',
        ,
    

你的“entry-point.browserify.js”可以是一个 ES6 文件,在模板中加载你的 react 应用程序:

import React from 'react';
import ReactDOM from 'react-dom';
import App from './components/app.js';
import "babel-polyfill";

import  Provider  from 'react-redux';
import  createStore, applyMiddleware  from 'redux';
import promise from 'redux-promise';
import reducers from './reducers/index.js';

const createStoreWithMiddleware = applyMiddleware(
  promise
)(createStore);

ReactDOM.render(
  <Provider store=createStoreWithMiddleware(reducers)>
    <App/>
  </Provider>
  , document.getElementById('my-react-app')
);

在您的 django 模板中,您现在可以轻松加载您的应用:

% load pipeline %

% comment % 
`browserify` is a PIPELINE key setup in the settings for django 
 pipeline. See the example above
% endcomment %

% javascript 'browserify' %

% comment % 
the app will be loaded here thanks to the entry point you created 
in PIPELINE settings. The key is the `entry-point.browserify.js` 
responsable to inject with ReactDOM.render() you react app in the div 
below
% endcomment %
<div id="my-react-app"></div>

使用 django-pipeline 的优点是静态在collectstatic 期间得到处理。

【讨论】:

【参考方案5】:

第一种方法是构建单独的 Django 和 React 应用程序。 Django 将负责提供使用 Django REST 框架构建的 API,React 将使用 Axios 客户端或浏览器的 fetch API 使用这些 API。 您需要有两台服务器,用于开发和生产,一台用于 Django(REST API),另一台用于 React(提供静态文件)

第二种方法不同前端和后端应用将耦合。基本上,您将使用 Django 来为 React 前端提供服务并公开 REST API。所以你需要将 React 和 Webpack 与 Django 集成,这些是你可以遵循的步骤

首先生成你的 Django 项目,然后在这个项目目录中使用 React CLI 生成你的 React 应用程序

对于 Django 项目,使用 pip 安装 django-webpack-loader

pip install django-webpack-loader

接下来将应用添加到已安装的应用中,并通过添加以下对象在settings.py 中进行配置

WEBPACK_LOADER = 
    'DEFAULT': 
            'BUNDLE_DIR_NAME': '',
            'STATS_FILE': os.path.join(BASE_DIR, 'webpack-stats.json'),
        

然后添加一个 Django 模板,该模板将用于挂载 React 应用程序并由 Django 提供服务

 % load render_bundle from webpack_loader % 

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width" />
    <title>Django + React </title>
  </head>
  <body>
    <div id="root">
     This is where React will be mounted
    </div>
     % render_bundle 'main' % 
  </body>
</html>

然后在urls.py 中添加一个 URL 来服务这个模板

from django.conf.urls import url
from django.contrib import admin
from django.views.generic import TemplateView

urlpatterns = [

    url(r'^', TemplateView.as_view(template_name="main.html")),

]

如果此时您同时启动 Django 和 React 服务器,您将收到一个 Django 错误,指出 webpack-stats.json 不存在。所以接下来你需要让你的 React 应用程序能够生成统计文件。

继续并在您的 React 应用中导航,然后安装 webpack-bundle-tracker

npm install webpack-bundle-tracker --save

然后弹出你的Webpack配置并转到config/webpack.config.dev.js然后添加

var BundleTracker  = require('webpack-bundle-tracker');
//...

module.exports = 

    plugins: [
          new BundleTracker(path: "../", filename: 'webpack-stats.json'),
    ]

这会将BundleTracker插件添加到Webpack并指示它在父文件夹中生成webpack-stats.json

确保在 config/webpack.config.prod.js 中也为生产执行相同的操作。

现在,如果你重新运行你的 React 服务器,webpack-stats.json 将被生成,Django 将能够使用它来查找有关由 React 开发服务器生成的 Webpack 包的信息。

还有一些事情要做。您可以从此tutorial 找到更多信息。

【讨论】:

你需要以耦合方式运行的 webpack-dev-server 吗?因为在教程中他正在运行它。据我了解,它需要运行,因为 django 使用它来保持包的更新。这是正确的吗?如果这是在生产中如何工作,即我还需要两台服务器吗? 在开发中,您需要同时运行 Django 开发服务器和 React/Webpack 开发服务器。在生产环境中,您只需要运行一台服务器 (Django),因为 Django 将负责提供由 npm run build 生成的构建文件 感谢您的澄清。 你能详细说明第一种方法吗?据我了解,它将包含一个正在运行的express 服务器,它将为 React 静态 JS 文件提供服务,并且 JS 文件将执行 ajax 请求以从 Django 服务器获取数据。浏览器首先访问express 服务器,它对Django 没有任何想法。我对么?使用这种方法可以实现像服务器端渲染这样的东西吗? 您可以简单地为您的静态文件使用静态主机和 CDN。例如,您可以使用 GitHub Pages 来托管 React 应用程序和 CloudFlare 作为 CDN。对于服务器端渲染,您需要另一种设置,例如使用 Express 服务器,但也有静态托管服务提供服务器端渲染,例如 Netlify。【参考方案6】:

来自后端或基于 Django 的角色并尝试使用 ReactJS 的任何人的注意事项:没有人能够在第一次尝试中成功设置 ReactJS 环境 :)

有一个来自 Owais Lone 的博客,可从http://owaislone.org/blog/webpack-plus-reactjs-and-django/ 获得;但是 Webpack 配置的语法已经过时了。

我建议你按照博客中提到的步骤,将webpack配置文件替换为下面的内容。但是,如果您对 Django 和 React 都是新手,请一次咀嚼一个,因为学习曲线可能会让您感到沮丧。

var path = require('path');
var webpack = require('webpack');
var BundleTracker = require('webpack-bundle-tracker');

module.exports = 
    context: __dirname,
    entry: './static/assets/js/index',
    output: 
        path: path.resolve('./static/assets/bundles/'),
        filename: '[name]-[hash].js'
    ,
    plugins: [
        new BundleTracker(filename: './webpack-stats.json')
    ],

 module: 
    loaders: [
      
        test: /\.jsx?$/,
        loader: 'babel-loader',
        exclude: /node_modules/,
        query: 
          presets: ['es2015', 'react']
        
      
    ]
  ,


  resolve: 
        modules: ['node_modules', 'bower_components'],
        extensions: ['.js', '.jsx']
    
;

【讨论】:

【参考方案7】:

接受的答案让我相信,无论如何解耦 Django 后端和 React 前端都是正确的方法。事实上,有一些方法可以将 React 和 Django 结合起来,这可能更适合特定情况。

This tutorial 很好地解释了这一点。特别是:

我看到了以下模式(几乎每个 Web 框架都很常见):

-React 在它自己的“前端”Django 应用程序中:加载单个 HTML 模板并让 React 管理前端(难度:中等)

-Django REST 作为独立 API + React 作为独立 SPA(难度:难,涉及到 JWT 进行身份验证)

-混合搭配:Django 模板中的迷你 React 应用程序(难度:简单)

【讨论】:

【参考方案8】:

我知道这已经晚了几年,但我会把它放在那里,以供下一个踏上旅程的人使用。

与 DjangoRESTFramework 相比,GraphQL 很有帮助,也更容易。就您获得的响应而言,它也更加灵活。你得到你想要的,而不必过滤响应来得到你想要的。

您可以在服务器端使用 Graphene Django 和 React+Apollo/Relay...您可以查看它,因为这不是您的问题。

【讨论】:

Graphene 和 React + Apollo 是一个优秀的堆栈!编写的 Python 比 DRF 略多,但 JS 代码大大减少,特别是因为 Apollo 消除了对 redux 的需求。【参考方案9】:

您可以尝试以下教程,它可能会帮助您前进:

Serving React and Django together

【讨论】:

以上是关于如何让 Django 和 ReactJS 一起工作?的主要内容,如果未能解决你的问题,请参考以下文章

如何修复 Reactjs、Django、Django Rest Frame 工作项目中的“net::ERR_CONNECTION_REFUSED 和错误:网络错误”错误

带有 ReactJS 的 Django 表单

你如何让亚马逊 SQS 与 Django celery 一起工作

我如何一起使用passportjs和reactjs?

如何将 localStorage 与 apollo-client 和 reactjs 一起使用?

了解 ReactJS 和 NodeJS 应用程序如何工作