Как заставить Django и ReactJS работать вместе?

Новое для Django и еще более новое для ReactJS. Я смотрел в AngularJS и ReactJS, но решил ReactJS. Похоже, что AngularJS опустился до популярности, несмотря на то, что AngularJS имеет больше доли рынка, и ReactJS, как говорят, быстрее набирает обороты.

Все, что отбросило в сторону, я начал изучать Удэми, и после нескольких видеороликов было важно увидеть, насколько хорошо он интегрируется с Django. То есть, когда я неизбежно врезался в стену, просто поднимая ее и работая, какая документация там, чтобы я не вращал свои колеса несколько часов и ночей.

На самом деле нет полных обучающих программ или пакетов pip, с которыми я столкнулся. Немногие, с которыми я столкнулся, не работали или были датированы, например, pyreact.

Мне показалось, что я просто должен рассматривать ReactJS совершенно отдельно, но учитывая классы и идентификаторы, я хочу, чтобы компоненты ReactJS отображались. После того, как отдельные компоненты ReactJS скомпилированы в один файл ES5, просто импортируйте этот единственный файл в шаблон Django.

Я думаю, что это будет быстро разбиваться, когда я получаю рендеринг от моделей Django, хотя Django Rest Framework выглядит так, как будто он задействован. Даже не достаточно далеко, чтобы увидеть, как Redux влияет на все это.

В любом случае, у кого есть четкий способ использования Django и ReactJS, которые они хотят разделить?

Во всяком случае, документация и учебные пособия изобилуют для AngularJS и Django, поэтому заманчиво просто пойти по этому пути, чтобы начать работу с любой интерфейсной инфраструктурой... Не лучшая причина.

Ответ 1

У меня нет опыта работы с Django, но концепции от front-end до back-end и front-end framework-framework одинаковы.

  1. React будет использовать ваш Django REST API. Фронт-энд и бэк-энд никак не связаны. React сделает HTTP-запросы к вашему REST API для получения и установки данных.
  2. React, с помощью Webpack ( связка модулей) и Babel (транспортировщик), объединит и перенесет ваш Javascript в один или несколько файлов, которые будут размещены на входной HTML-странице. Изучите Webpack, Babel, Javascript и React и Redux (контейнер состояния). Я полагаю, что вы не будете использовать шаблоны Django, но вместо этого позволите React визуализировать интерфейс.
  3. Когда эта страница отображается, React будет использовать API для извлечения данных, чтобы React мог ее отобразить. Ваше понимание HTTP-запросов, Javascript (ES6), Promises, Middleware и React является здесь важным.

Вот несколько вещей, которые я нашел в Интернете, которые должны помочь (на основе быстрого поиска в Google):

Надеюсь, это направит вас в правильном направлении! Удачи! Надеюсь, что другие, которые специализируются на Django, могут добавить к моему ответу.

Ответ 2

Я чувствую вашу боль, поскольку я тоже начинаю работать Django и React.js. Было ли несколько проектов Django, и я думаю, React.js отлично подходит для Django. Однако, это может быть пугающе начать. Мы стоим на плечах гигантов здесь;)

Вот как я думаю, все работает вместе (большая картина, пожалуйста, кто-то поправьте меня, если я ошибаюсь).

  • Django и его база данных (я предпочитаю Postgres) с одной стороны (бэкэнд)
  • Django Rest-framework, обеспечивающий интерфейс для внешнего мира (т.е. мобильных приложений и реактивов и т.д.)
  • Reactjs, Nodejs, Webpack, Redux (или, возможно, MobX?) с другой стороны (интерфейс)

Связь между Django и 'frontend' выполняется через платформу Rest. Убедитесь, что вы получили авторизацию и разрешения для среды Rest на месте.

Я нашел хороший шаблон котла для этого сценария, и он работает из коробки. Просто следуйте readme 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.

Я надеюсь, что это поможет.

Ответ 3

Как вам ответили другие, если вы создаете новый проект, вы можете разделить интерфейс и бэкэнд и использовать любой плагин rest из django для создания API-интерфейса rest rest для вашего интерфейса. Это в идеальном мире.

Если у вас уже есть проект с шаблонизатором django, вы должны загрузить рендеринг реагирования на страницу, на которую вы хотите загрузить приложение. В моем случае у меня уже был django-конвейер, и я просто добавил расширение browserify. (https://github.com/j0hnsmith/django-pipeline-browserify)

Как и в примере, я загрузил приложение, используя django-pipe:

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

Ваш "entry-point.browserify.js" может быть файлом ES6, который загружает ваше приложение реакции в шаблон:

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-pipel в том, что статические данные обрабатываются во время collectstatic.

Ответ 4

Первый подход заключается в создании отдельных приложений Django и React. Django будет нести ответственность за обслуживание API, созданного с использованием инфраструктуры Django REST, и React будет использовать эти API с помощью клиента Axios или API выборки из браузера. Вам понадобится два сервера, как для разработки, так и для производства: один для Django (REST API) и другой для React (для обслуживания статических файлов).

Второй подход заключается в том, что внешние и бэкенд-приложения будут связаны. В основном вы будете использовать Django как для обслуживания внешнего интерфейса React, так и для предоставления REST API. Таким образом, вам нужно интегрировать React и Webpack с Django, вот шаги, которые вы можете выполнить, чтобы сделать это

Сначала сгенерируйте проект Django, а затем в этом каталоге проекта сгенерируйте приложение React с помощью React CLI.

Для проекта Django установите django-webpack-loader с помощью pip:

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>

Затем добавьте URL в 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 генерировать webpack-stats.json в родительской папке.

Обязательно сделайте то же самое в config/webpack.config.prod.js для производства.

Теперь, если вы перезапустите сервер React, будет сгенерирован webpack-stats.json, и Django сможет использовать его для поиска информации о пакетах Webpack, сгенерированных сервером React dev.

Есть и другие вещи. Вы можете найти больше информации из этого урока.

Ответ 5

Примечание для тех, кто работает в бэкэнде или на основе Django и пытается работать с ReactJS: никому не удается успешно настроить среду ReactJS с первой попытки :)

Есть блог от Owais Lone, который доступен по адресу http://owaislone.org/blog/webpack-plus-reactjs-and-django/; однако синтаксис в конфигурации 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']
    }
};

Ответ 6

Принятый ответ привел меня к мысли, что разделение бэкэнда Django и React Frontend - верный путь, несмотря ни на что. На самом деле существуют подходы, в которых React и Django связаны, что может лучше подходить в конкретных ситуациях.

Этот урок хорошо объясняет это. Особенно:

Я вижу следующие шаблоны (которые являются общими почти для всех веб-фреймворков):

-React в своем собственном "внешнем" приложении Django: загрузите один HTML-шаблон и позвольте React управлять внешним интерфейсом (сложность: средняя)

-Django REST в качестве отдельного API + Реагирование в качестве отдельного SPA (сложность: сложная, для аутентификации используется JWT)

-Mix и соответствуйте: мини-приложения React в шаблонах Django (сложность: простая)

Ответ 9

Я знаю, что это на пару лет позже, но я выкладываю это для следующего человека в этом путешествии.

GraphQL полезен и намного проще по сравнению с DjangoRESTFramework. Это также более гибко с точки зрения ответов, которые вы получаете. Вы получаете то, что просите, и вам не нужно фильтровать ответ, чтобы получить то, что вы хотите.

Вы можете использовать Graphene Django на стороне сервера и React + Apollo/Relay... Вы можете посмотреть на это, поскольку это не ваш вопрос.