¿Cómo hacer que Django y ReactJS trabajen juntos?

138

Nuevo en Django e incluso más nuevo en ReactJS. He estado buscando en AngularJS y ReactJS, pero me decidí por ReactJS. Parecía que estaba superando a AngularJS en cuanto a popularidad a pesar de que AngularJS tenía más participación en el mercado, y se dice que ReactJS es más rápido para recoger.

Dejando a un lado toda esa basura, comencé a tomar un curso sobre Udemy y después de algunos videos me pareció importante ver qué tan bien se integra con Django. Es entonces cuando inevitablemente choco contra una pared simplemente poniéndolo en funcionamiento, qué tipo de documentación existe para que no gire mis ruedas durante varias horas y noches.

Realmente no hay tutoriales completos o pippaquetes, me encontré. Los pocos que encontré no funcionaban o estaban anticuados, pyreactpor ejemplo.

Un pensamiento que tenía era tratar a ReactJS completamente por separado, pero teniendo en cuenta las clases y los ID que quiero que los componentes de ReactJS se procesen. Después de que los componentes de ReactJS se compilen en un solo archivo ES5, solo importe ese único archivo en Django modelo.

Creo que eso se descompondrá rápidamente cuando llegue a renderizar desde los modelos de Django, aunque el Django Rest Framework parece estar involucrado. Ni siquiera lo suficiente como para ver cómo Redux afecta todo esto.

De todos modos, ¿alguien tiene una forma clara de usar Django y ReactJS que les interesa compartir?

En cualquier caso, la documentación y los tutoriales son abundantes para AngularJS y Django, por lo que es tentador seguir ese camino para comenzar con cualquier marco de front-end ... No es la mejor razón.

eox.dev
fuente
2
Tenía curiosidades similares y configuré una aplicación de ejemplo para react + webpack + django: el repositorio también enlaza con algunas herramientas y artículos relacionados que podrían ser útiles.
danwild

Respuestas:

142

No tengo experiencia con Django, pero los conceptos de front-end a back-end y front-end framework a framework son los mismos.

  1. React consumirá su API REST de Django . Los front-end y back-end no están conectados de ninguna manera. React realizará solicitudes HTTP a su API REST para obtener y establecer datos.
  2. React, con la ayuda de Webpack (agrupador de módulos) y Babel (transpiler) , agrupará y transpilará su Javascript en archivos únicos o múltiples que se colocarán en la página HTML de entrada. Aprenda Webpack, Babel, Javascript y React y Redux (un contenedor de estado) . Yo creo que no va a usar plantillas de Django, sino que permiten reaccionar para hacer que el front-end.
  3. A medida que se procesa esta página, React consumirá la API para obtener datos para que React pueda procesarla. Su comprensión de las solicitudes HTTP, Javascript (ES6), Promesas, Middleware y React es esencial aquí.

Aquí hay algunas cosas que he encontrado en la web que deberían ayudar (basado en una búsqueda rápida en Google):

¡Espero que esto te lleve en la dirección correcta! ¡Buena suerte! Esperemos que otros que se especialicen en Django puedan agregar a mi respuesta.

KA01
fuente
Veré el tutorial de YouTube. Revisé ambos tutoriales anteriormente. El artículo 1 no funcionó aunque lo seguí de cerca. (Copié y pegué la mayor parte del código). Eso está en un proyecto existente, pero intentaré uno nuevo. El artículo 2 utilizaba paquetes obsoletos y no se había actualizado recientemente. De todos modos, al leer más sobre AngularJS y Django, parece que la API REST de Django todavía se usa. Supongo que estaba buscando una solución sin agregar esa dimensión, pero parece que es inevitable.
eox.dev
Ok, actualicé un poco mi respuesta sacando el artículo desactualizado. Tiene más de 2 años, por lo que definitivamente debe eliminarse. ¿Ayudan las balas numeradas? ¿Qué tienes problemas para entender?
KA01
1
Después de probar el segundo enlace varias veces más en proyectos existentes y proyectos nuevos, al menos conseguí que hablaran. La línea {% render_bundle 'main' %}está mal y debería estarlo {% render_bundle "main" %}.
eox.dev
1
El segundo enlace no funciona. Por favor actualice el enlace.
Aditya Mishra
1
Reemplazaría ese segundo enlace muerto con este artículo, seguí esto y funciona principalmente ... medium.com/labcodes/configuring-django-with-react-4c599d1eae63
Doug F
36

Siento tu dolor cuando yo también estoy empezando a hacer que Django y React.js trabajen juntos. Hice un par de proyectos de Django, y creo que React.js es una gran combinación para Django. Sin embargo, puede ser intimidante comenzar. Estamos parados sobre los hombros de gigantes aquí;)

Así es como pienso, todo funciona en conjunto (panorama general, por favor alguien corríjame si me equivoco).

  • Django y su base de datos (prefiero Postgres) en un lado (backend)
  • Django Rest-framework que proporciona la interfaz al mundo exterior (es decir, aplicaciones móviles y React y tal)
  • Reactjs, Nodejs, Webpack, Redux (o tal vez MobX?) En el otro lado (frontend)

La comunicación entre Django y 'la interfaz' se realiza a través del marco Rest. Asegúrese de obtener su autorización y permisos para el marco Rest en su lugar.

Encontré una buena plantilla de caldera para exactamente este escenario y funciona de inmediato. Simplemente siga el archivo léame https://github.com/scottwoodall/django-react-template y una vez que haya terminado, tendrá un proyecto bastante bueno de Django Reactjs en ejecución. ¡De ninguna manera esto está destinado a la producción, sino más bien como una forma de profundizar y ver cómo las cosas están conectadas y funcionando!

Un pequeño cambio que me gustaría sugerir es este: siga las instrucciones de configuración PERO antes de llegar al segundo paso para configurar el backend (Django aquí https://github.com/scottwoodall/django-react-template/blob/master /backend/README.md ), cambie el archivo de requisitos para la configuración.

Encontrará el archivo en su proyecto en /backend/requirements/common.pip Reemplace su contenido con esto

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

Esto le ofrece la última versión estable para Django y su marco de descanso.

Espero que eso ayude.

imolitor
fuente
44
Un año después, cambié a VUE.js ( vuejs.org ). Lo hice funcionar con las plantillas de Django y se comunicará con la base de datos a través del Django Rest Framework. Es rápido y ligero (~ 20kb)
imolitor el
17

Como otros le respondieron, si está creando un nuevo proyecto, puede separar el frontend y el backend y usar cualquier complemento django rest para crear una API de descanso para su aplicación frontend. Esto está en el mundo ideal.

Si tiene un proyecto con la plantilla de django ya en su lugar, debe cargar su render de reacción dom en la página que desea cargar la aplicación. En mi caso, ya tenía django-pipeline y acabo de agregar la extensión browserify. ( https://github.com/j0hnsmith/django-pipeline-browserify )

Como en el ejemplo, cargué la aplicación usando django-pipeline:

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

Su " entry-point.browserify.js " puede ser un archivo ES6 que carga su aplicación de reacción en la plantilla:

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

En su plantilla de django, ahora puede cargar su aplicación fácilmente:

{% 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>

La ventaja de usar django-pipeline es que las estadísticas se procesan durante el collectstatic.

Karim N Gorjux
fuente
10

El primer enfoque es crear aplicaciones separadas de Django y React. Django será responsable de servir la API construida usando el marco Django REST y React consumirá estas API usando el cliente Axios o la API de búsqueda del navegador. Necesitará tener dos servidores, tanto en desarrollo como en producción, uno para Django (REST API) y otro para React (para servir archivos estáticos) .

El segundo enfoque es diferente: las aplicaciones frontend y backend estarán acopladas . Básicamente usará Django para servir la interfaz React y para exponer la API REST. Por lo tanto, deberá integrar React y Webpack con Django, estos son los pasos que puede seguir para hacerlo.

Primero genere su proyecto Django, luego dentro de este directorio del proyecto, genere su aplicación React usando la CLI React

Para el proyecto Django, instale django-webpack-loader con pip:

pip install django-webpack-loader

A continuación, agregue la aplicación a las aplicaciones instaladas y configúrela settings.pyagregando el siguiente objeto

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

Luego agregue una plantilla de Django que se usará para montar la aplicación React y será servida por 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>

Luego agregue una URL urls.pypara servir esta plantilla

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")),

]

Si inicia los servidores Django y React en este punto, recibirá un error de Django que dice webpack-stats.jsonque no existe. A continuación, debe hacer que su aplicación React pueda generar el archivo de estadísticas.

Siga adelante y navegue dentro de su aplicación React, luego instale webpack-bundle-tracker

npm install webpack-bundle-tracker --save

Luego expulse la configuración de su paquete web y vaya a config/webpack.config.dev.jsagregar

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

module.exports = {

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

Esto agrega el complemento BundleTracker a Webpack y le indica que se genere webpack-stats.jsonen la carpeta principal.

Asegúrese también de hacer lo mismo config/webpack.config.prod.jspara la producción.

Ahora, si vuelve a ejecutar su servidor React webpack-stats.json, se generará y Django podrá consumirlo para encontrar información sobre los paquetes Webpack generados por el servidor de desarrollo React.

Hay algunas otras cosas para. Puede encontrar más información en este tutorial .

Ahmed Bouchefra
fuente
¿Necesita webpack-dev-server ejecutándose en un enfoque acoplado? Porque en el tutorial lo está ejecutando. Según tengo entendido, debe ejecutarse porque lo usa django para mantener actualizados los paquetes. ¿Es esto correcto? Si es así, ¿cómo funcionaría esto en producción, es decir, si todavía necesitaría dos servidores?
Pavlee
1
En desarrollo, necesitará tanto el servidor de desarrollo Django como el servidor de desarrollo React / Webpack en ejecución. En producción solo necesita un servidor (Django) en ejecución porque Django se encargará de servir los archivos generados generados pornpm run build
Ahmed Bouchefra
Gracias por la aclaración.
Pavlee
¿Puedes dar más detalles sobre el primer enfoque? Por lo que entiendo, contendría un expressservidor en ejecución que servirá React archivos JS estáticos y que los archivos JS harían una solicitud ajax para obtener datos del servidor Django. El navegador primero golpea el expressservidor, no tiene idea sobre el Django. ¿Estoy en lo correcto? ¿Es posible hacer algo así como la representación del lado del servidor con este enfoque?
yadav_vi
Simplemente puede usar un host estático y un CDN para sus archivos estáticos. Por ejemplo, puede usar las páginas de GitHub para alojar la aplicación React y CloudFlare como CDN. Para la representación del lado del servidor, necesita otra configuración, como usar un servidor Express, PERO también hay servicios de alojamiento estático que ofrecen la representación del lado del servidor como Netlify.
Ahmed Bouchefra
10

Una nota para cualquier persona que provenga de un backend o un rol basado en Django e intente trabajar con ReactJS: nadie logra configurar el entorno ReactJS con éxito en el primer intento :)

Hay un blog de Owais Lone que está disponible en http://owaislone.org/blog/webpack-plus-reactjs-and-django/ ; sin embargo, la sintaxis en la configuración de Webpack está desactualizada.

Le sugiero que siga los pasos mencionados en el blog y reemplace el archivo de configuración del paquete web con el contenido a continuación. Sin embargo, si eres nuevo tanto en Django como en React, mastica uno a la vez debido a la curva de aprendizaje, probablemente te sentirás frustrado.

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']
    }
};
IVI
fuente
¡La nota al principio es realmente alentadora!
Mohammed Shareef C
7

La respuesta aceptada me lleva a creer que desacoplar el backend de Django y React Frontend es el camino correcto a seguir, pase lo que pase. De hecho, existen enfoques en los que React y Django están acoplados, que pueden ser más adecuados en situaciones particulares.

Este tutorial explica bien esto. En particular:

Veo los siguientes patrones (que son comunes a casi todos los marcos web):

- Reaccione en su propia aplicación Django “frontend”: cargue una sola plantilla HTML y deje que React administre la interfaz (dificultad: media)

-Django REST como una API independiente + Reaccionar como un SPA independiente (dificultad: difícil, implica JWT para la autenticación)

-Mezclar y combinar: aplicaciones mini React dentro de las plantillas de Django (dificultad: simple)

Rexcirus
fuente
1

Sé que esto lleva un par de años de retraso, pero lo voy a presentar para la próxima persona en este viaje.

GraphQL ha sido útil y mucho más fácil en comparación con DjangoRESTFramework. También es más flexible en términos de las respuestas que obtienes. Obtiene lo que pide y no tiene que filtrar la respuesta para obtener lo que desea.

Puede usar Graphene Django en el lado del servidor y React + Apollo / Relay ... Puede investigarlo ya que esa no es su pregunta.

K_Wainaina
fuente
¡Graphene and React + Apollo es una pila excelente! Un poco más de Python para escribir que DRF, pero una enorme reducción en el código JS, especialmente porque Apollo mata la necesidad de redux.
John Ottenlips