如何使Django和ReactJS一起工作?


138

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来说是很多的,因此很容易采取这种方法来开始使用任何前端框架……这不是最好的原因。


2
我也有类似的好奇心,并为react + webpack + django 设置了一个示例应用程序-存储库还链接到一些可能有用的相关工具和文章。
danwild

Answers:


142

我没有Django的经验,但是从前端到后端以及前端框架到框架的概念是相同的。

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

下面是我在网络上发现了几件事情应该帮助(基于一个快速谷歌搜索):

希望这会指引您正确的方向!祝好运!希望其他专门研究Django的人可以加入我的回复。


我将检查YouTube教程。我以前确实看过这两个教程。第1条没有用,尽管我密切关注。(复制并粘贴了大部分代码)。那是在一个现有的项目上,但是我会尝试一个新的。第2条使用了已弃用的软件包,并且最近未更新。无论如何,阅读有关AngularJS和Django的更多信息,听起来好像仍在使用Django REST API。我想我一直在寻找一个解决方案而未添加该维度,但是听起来这是不可避免的。
eox.dev

好的,我通过删除过时的文章来更新了我的答案。它已经使用了2年以上,因此绝对需要将其删除。编号的子弹有帮助吗?您在理解上有什么困难?
KA01

1
在现有项目和全新项目上多次尝试第二个链接后,我至少让他们谈论了。这行{% render_bundle 'main' %}是错误的,应该是{% render_bundle "main" %}
eox.dev

1
第二个链接不起作用。请更新链接。
阿迪亚·米什拉

1
我将用这篇文章替换
Doug F

36

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

我的想法是这样,它们都可以一起工作(大图,如果我错了,请有人纠正我)。

  • 一侧(后端)上的Django及其数据库(我更喜欢Postgres)
  • Django Rest-framework提供与外界的接口(即,Mobile Apps和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框架的最新稳定版本。

希望对您有所帮助。


4
一年后,我切换到了VUE.js(vuejs.org)。我将其与Django模板一起使用,它将通过Django Rest Framework与数据库进行通信。它又快又轻(
〜20kb

17

正如其他人回答的那样,如果您要创建一个新项目,则可以将前端和后端分开,并使用任何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


10

第一种方法是构建单独的Django和React应用程序。Django将负责提供使用Django REST框架构建的API,React将使用Axios客户端或浏览器的访存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以提供此模板

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捆绑包的信息。

还有其他一些事情。您可以从本教程中找到更多信息。


您是否需要以耦合方式运行webpack-dev-server?因为在教程中他正在运行它。据我了解,它需要运行,因为django使用它来保持软件包更新。这是正确的吗?如果这将如何在生产中工作,即我仍需要两台服务器?
pavlee

1
在开发中,您需要同时运行Django开发服务器和React / Webpack开发服务器。在生产中,您只需要运行一台服务器(Django),因为Django将负责处理npm run build
Ahmed Bouchefra

感谢您的澄清。
pavlee

您能否详细介绍第一种方法?据我了解,它将包含一个express正在运行的服务器,该服务器将为React静态JS文件提供服务,并且该JS文件将发出ajax请求以从Django服务器获取数据。浏览器首先访问express服务器,但对Django并没有任何了解。我对么?这种方法是否可以实现类似服务器端渲染的功能?
yadav_vi '18

您可以简单地将静态主机和CDN用于静态文件。例如,您可以使用GitHub Pages将React应用程序和CloudFlare托管为CDN。对于服务器端渲染,您需要另一种设置,例如使用Express服务器但还有一些静态托管服务,这些服务可以提供服务器端渲染,例如Netlify。
艾哈迈德·布彻夫拉

10

给任何来自后端角色或基于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']
    }
};

开头的注解确实令人鼓舞!
Mohammed Shareef C

7

公认的答案使我相信,无论如何,将Django后端和React Frontend分离都是正确的方法。实际上,有一些方法可以将React和Django耦合在一起,这可能更适合特定情况。

本教程对此进行了很好的解释。特别是:

我看到以下模式(几乎每个Web框架都通用):

-在其自己的“前端” Django应用程序中进行反应:加载单个HTML模板,然后让React管理前端(难度:中等)

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

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



1

我知道这已经晚了几年了,但是我准备把它发布给下一个人。

与DjangoRESTFramework相比,GraphQL很有帮助,而且方法也更简单。就您得到的答复而言,它也更加灵活。您可以得到想要的东西,而不必通过响应进行筛选就可以得到想要的东西。

您可以在服务器端使用Graphene Django,并在React + Apollo / Relay中使用...。您可以对其进行研究,因为这不是您的问题。


石墨烯和React + Apollo是出色的堆栈!与DRF相比,Python编写的代码要多一些,但是JS代码的大量减少,尤其是因为Apollo消除了对redux的需求。
John Ottenlips
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.