Jak zmusić Django i ReactJS do współpracy?

138

Nowość w Django i jeszcze nowsza w ReactJS. Zaglądałem do AngularJS i ReactJS, ale zdecydowałem się na ReactJS. Wydawało się, że wyprzedza AngularJS pod względem popularności, mimo że AngularJS ma większy udział w rynku, a ReactJS jest szybszy do odbioru.

Pomijając te wszystkie śmieci, zacząłem brać udział w kursie Udemy i po kilku filmach wydawało się ważne, aby zobaczyć, jak dobrze integruje się z Django. Wtedy nieuchronnie uderzam w ścianę, tylko ją uruchamiając, jaka jest dokumentacja, żebym nie kręcił kołami przez kilka godzin i nocy.

Naprawdę nie ma żadnych kompleksowych samouczków ani pippakietów, na które się natknąłem. Na przykład kilka, na które się natknąłem, nie działało lub było datowanych pyreact.

Pomyślałem, że po prostu potraktować ReactJS całkowicie osobno, ale biorąc pod uwagę klasy i identyfikatory, w których chcę renderować komponenty ReactJS. Po skompilowaniu oddzielnych komponentów ReactJS do pojedynczego pliku ES5, po prostu zaimportuj ten pojedynczy plik do Django szablon.

Myślę, że to szybko się załamie, kiedy przejdę do renderowania z modeli Django, chociaż Django Rest Framework wydaje się być w to zaangażowany. Nie na tyle daleko, by zobaczyć, jak Redux wpływa na to wszystko.

W każdym razie, czy ktoś ma jasny sposób, w jaki używa Django i ReactJS, którymi chce się podzielić?

W każdym razie dokumentacja i samouczki są obfite dla AngularJS i Django, więc kuszące jest, aby po prostu pójść tą drogą, aby rozpocząć pracę z dowolnym frameworkiem front-end ... Nie jest to najlepszy powód.

eox.dev
źródło
2
Miałem podobne ciekawostki i skonfigurowałem przykładową aplikację dla react + webpack + django - repozytorium zawiera również linki do niektórych powiązanych narzędzi i artykułów, które mogą być przydatne.
danwild

Odpowiedzi:

142

Nie mam doświadczenia z Django, ale koncepcje od front-endu do back-endu i front-end framework do frameworka są takie same.

  1. React zużyje Twój interfejs API REST Django . Front-endy i back-endy nie są w żaden sposób połączone. React będzie wysyłać żądania HTTP do Twojego REST API w celu pobrania i ustawienia danych.
  2. React, z pomocą Webpack (pakiet modułów) i Babel (transpiler) , połączy i przetransponuje Twój JavaScript do jednego lub wielu plików, które zostaną umieszczone na stronie wejściowej HTML. Naucz się Webpack, Babel, Javascript oraz React and Redux (kontener stanu) . I wierzę , że nie będzie używać Django templating ale zamiast pozwalają React do renderowania front-end.
  3. Kiedy ta strona jest renderowana, React zużywa API do pobierania danych, aby React mógł je renderować. Twoje zrozumienie żądań HTTP, JavaScript (ES6), Promises, Middleware i React jest tutaj niezbędne.

Oto kilka rzeczy, które znalazłem w sieci, które powinny pomóc (na podstawie szybkiego wyszukiwania w Google):

Mam nadzieję, że to poprowadzi Cię we właściwym kierunku! Powodzenia! Mam nadzieję, że inni specjalizujący się w Django mogą dodać do mojej odpowiedzi.

KA01
źródło
Zajrzę do samouczka YouTube. Wcześniej przeszedłem przez oba te samouczki. Artykuł 1 nie zadziałał, chociaż uważnie go przestrzegałem. (Skopiowano i wklejono większość kodu). To dotyczy istniejącego projektu, ale spróbuję nowego. Artykuł 2 wykorzystywał przestarzałe pakiety i nie był ostatnio aktualizowany. W każdym razie, czytając więcej o AngularJS i Django, wygląda na to, że Django REST API jest nadal używane. Chyba szukałem rozwiązania bez dodawania tego wymiaru, ale wygląda na to, że jest to nieuniknione.
eox.dev
Ok, zaktualizowałem trochę moją odpowiedź, usuwając nieaktualny artykuł. Ma ponad 2 lata, więc zdecydowanie należało go usunąć. Czy ponumerowane punktory pomagają? Czego nie rozumiesz?
KA01
1
Po kilkukrotnym wypróbowaniu drugiego łącza w istniejących projektach i zupełnie nowych projektach, udało mi się przynajmniej rozmawiać. Linia {% render_bundle 'main' %}jest zła i powinna być {% render_bundle "main" %}.
eox.dev
1
Drugie łącze nie działa. Zaktualizuj łącze.
Aditya Mishra
1
Zastąpiłbym ten martwy drugi link w tym artykule, śledziłem to i to głównie działa .. medium.com/labcodes/configuring-django-with-react-4c599d1eae63
Doug F
36

Czuję twój ból, gdy ja też zaczynam, aby Django i React.js współpracowały. Wykonałem kilka projektów Django i myślę, że React.js świetnie pasuje do Django. Jednak rozpoczęcie może być onieśmielające. Stoimy tu na ramionach gigantów;)

Oto jak myślę, wszystko działa razem (duży obraz, proszę, niech ktoś mnie poprawi, jeśli się mylę).

  • Django i jego baza danych (wolę Postgres) po jednej stronie (backend)
  • Framework Django Rest zapewniający interfejs do świata zewnętrznego (np. Mobile Apps i React i tym podobne)
  • Reactjs, Nodejs, Webpack, Redux (a może MobX?) Po drugiej stronie (frontend)

Komunikacja między Django a „frontendem” odbywa się za pośrednictwem struktury Rest. Upewnij się, że masz autoryzację i uprawnienia do struktury Rest.

Znalazłem dobry szablon kotła dla dokładnie tego scenariusza i działa po wyjęciu z pudełka. Po prostu postępuj zgodnie z readme https://github.com/scottwoodall/django-react-template, a gdy skończysz, masz uruchomiony całkiem niezły projekt Django Reactjs. W żadnym wypadku nie jest to przeznaczone do celów produkcyjnych, ale raczej jako sposób, abyś mógł zagłębić się i zobaczyć, jak wszystko jest połączone i działa!

Jedna drobna zmiana, którą chciałbym zasugerować, jest następująca: postępuj zgodnie z instrukcjami konfiguracji, ALE zanim przejdziesz do drugiego kroku, aby skonfigurować backend (Django tutaj https://github.com/scottwoodall/django-react-template/blob/master /backend/README.md ), zmień plik wymagań dla instalacji.

Plik znajdziesz w swoim projekcie pod adresem /backend/requirements/common.pip. Zastąp jego zawartość tym

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

w ten sposób otrzymasz najnowszą stabilną wersję Django i jego frameworka Rest.

Mam nadzieję że to pomogło.

imolitor
źródło
4
Rok później przeszedłem na VUE.js ( vuejs.org ). Sprawiłem, że działało z szablonami Django i będzie komunikować się z bazą danych za pośrednictwem Django Rest Framework. Jest szybki i lekki (~ 20kb)
imolitor
17

Jak odpowiedzieli ci inni, jeśli tworzysz nowy projekt, możesz oddzielić frontend i backend i użyć dowolnej wtyczki django rest, aby utworzyć rest api dla swojej aplikacji frontendowej. To jest w idealnym świecie.

Jeśli masz projekt z już utworzonym szablonem django, musisz załadować swój react dom render na stronie, na której chcesz załadować aplikację. W moim przypadku miałem już django-pipeline i właśnie dodałem rozszerzenie browserify. ( https://github.com/j0hnsmith/django-pipeline-browserify )

Jak w przykładzie, załadowałem aplikację za pomocą django-pipeline:

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

Twój „ entry-point.browserify.js ” może być plikiem ES6, który wczytuje Twoją aplikację React w szablonie:

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

W swoim szablonie django możesz teraz łatwo załadować swoją aplikację:

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

Zaletą korzystania z django-pipeline jest to, że statystyki są przetwarzane podczas collectstatic.

Karim N Gorjux
źródło
10

Pierwsze podejście polega na zbudowaniu oddzielnych aplikacji Django i React. Django będzie odpowiedzialne za obsługę API zbudowanego przy użyciu frameworka Django REST, a React będzie korzystał z tych API przy użyciu klienta Axios lub API pobierania przeglądarki. Będziesz potrzebował dwóch serwerów, zarówno w fazie rozwoju, jak i produkcji, jeden dla Django (REST API), a drugi dla React (do obsługi plików statycznych) .

Drugie podejście różni się tym, że aplikacje frontendowe i backendowe będą połączone . Zasadniczo będziesz używać Django zarówno do obsługi interfejsu użytkownika React, jak i do ujawniania REST API. Musisz więc zintegrować React i Webpack z Django, oto kroki, które możesz wykonać, aby to zrobić

Najpierw wygeneruj projekt Django, a następnie w tym katalogu projektu wygeneruj swoją aplikację React za pomocą interfejsu wiersza polecenia React

Dla projektu Django zainstaluj django-webpack-loader za pomocą pip:

pip install django-webpack-loader

Następnie dodaj aplikację do zainstalowanych aplikacji i skonfiguruj ją settings.py, dodając następujący obiekt

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

Następnie dodaj szablon Django, który zostanie użyty do zamontowania aplikacji React i będzie obsługiwany przez 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>

Następnie dodaj adres URL, urls.pyaby wyświetlić ten szablon

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

]

Jeśli w tym momencie uruchomisz zarówno serwery Django, jak i React, pojawi się błąd Django z informacją, że plik webpack-stats.jsonnie istnieje. Następnie musisz sprawić, by aplikacja React mogła generować plik statystyk.

Śmiało i przejdź do aplikacji React, a następnie zainstaluj webpack-bundle-tracker

npm install webpack-bundle-tracker --save

Następnie usuń konfigurację pakietu Webpack i przejdź do, config/webpack.config.dev.jsa następnie dodaj

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

module.exports = {

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

To dodaje wtyczkę BundleTracker do Webpacka i poinstruuje go, aby wygenerował webpack-stats.jsonw folderze nadrzędnym.

Upewnij się, że zrobisz to samo w config/webpack.config.prod.jsprodukcji.

Teraz, jeśli ponownie uruchomisz serwer React, webpack-stats.jsonzostanie wygenerowany i Django będzie mógł go wykorzystać, aby znaleźć informacje o pakietach Webpack wygenerowanych przez serwer deweloperski React.

Jest jeszcze kilka rzeczy do zrobienia. Więcej informacji znajdziesz w tym samouczku .

Ahmed Bouchefra
źródło
Czy potrzebujesz serwera webpack-dev-server działającego w połączeniu? Ponieważ w samouczku to prowadzi. Z mojego punktu widzenia musi być uruchamiany, ponieważ jest używany przez django do aktualizowania pakietów. Czy to jest poprawne? Jeśli tak, jak miałoby to działać w środowisku produkcyjnym, tj. Czy nadal potrzebowałbym dwóch serwerów?
pavlee
1
W rozwoju będziesz potrzebować zarówno serwera deweloperskiego Django, jak i serwera deweloperskiego React / Webpack działającego. W produkcji potrzebujesz tylko jednego serwera (Django) działającego, ponieważ Django zajmie się obsługą zbudowanych plików wygenerowanych przeznpm run build
Ahmed Bouchefra
Dzięki za wyjaśnienie.
pavlee
Czy możesz rozwinąć pierwsze podejście? Z tego, co rozumiem, zawierałby działający expressserwer, który będzie obsługiwał statyczne pliki JS React, a pliki JS wykonywałyby żądanie Ajax w celu pobrania danych z serwera Django. Przeglądarka najpierw trafia na expressserwer, nie ma pojęcia o Django. Mam rację? Czy przy takim podejściu można wykonać renderowanie po stronie serwera?
yadav_vi
Możesz po prostu użyć hosta statycznego i CDN dla plików statycznych. Na przykład możesz użyć GitHub Pages do hostowania aplikacji React i CloudFlare jako CDN. Do renderowania po stronie serwera potrzebujesz innej konfiguracji, takiej jak użycie serwera Express, ALE istnieją również statyczne usługi hostingowe, które oferują renderowanie po stronie serwera, takie jak Netlify.
Ahmed Bouchefra
10

Uwaga dla każdego, kto pochodzi z roli backendowej lub opartej na Django i próbuje pracować z ReactJS: Nikt nie jest w stanie pomyślnie skonfigurować środowiska ReactJS za pierwszym razem :)

Istnieje blog od Owais Lone, który jest dostępny pod adresem http://owaislone.org/blog/webpack-plus-reactjs-and-django/ ; jednak składnia konfiguracji WebPacka jest nieaktualna.

Proponuję wykonać kroki wymienione na blogu i zastąpić plik konfiguracyjny pakietu internetowego poniższą zawartością. Jeśli jednak nie znasz Django i Reacta, przeżuwaj pojedynczo ze względu na krzywą uczenia się, prawdopodobnie będziesz sfrustrowany.

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
źródło
Uwaga na początku jest naprawdę zachęcająca!
Mohammed Shareef C
7

Przyjęta odpowiedź prowadzi mnie do przekonania, że ​​oddzielenie backendu Django i interfejsu React jest właściwą drogą bez względu na wszystko. W rzeczywistości istnieją podejścia, w których React i Django są połączone, co może być lepiej dostosowane do określonych sytuacji.

Ten poradnik dobrze to wyjaśnia. W szczególności:

Widzę następujące wzorce (które są wspólne dla prawie każdego frameworka internetowego):

-React we własnej „frontendowej” aplikacji Django: załaduj pojedynczy szablon HTML i pozwól Reactowi zarządzać frontendem (trudność: średnia)

-Django REST jako samodzielne API + React jako samodzielne SPA (trudność: trudna, wymaga JWT do uwierzytelnienia)

-Mix and match: mini aplikacje React w szablonach Django (trudność: prosta)

Rexcirus
źródło
1

Wiem, że spóźnia się to kilka lat, ale udostępniam to następnej osobie w tej podróży.

GraphQL okazał się pomocny i znacznie łatwiejszy w porównaniu do DjangoRESTFramework. Jest również bardziej elastyczny pod względem otrzymywanych odpowiedzi. Dostajesz to, o co prosisz i nie musisz filtrować odpowiedzi, aby uzyskać to, czego chcesz.

Możesz używać Graphene Django po stronie serwera i React + Apollo / Relay ... Możesz się temu przyjrzeć, bo to nie jest twoje pytanie.

K_Wainaina
źródło
Grafen i React + Apollo to doskonały stack! Nieco więcej Pythona do pisania niż DRF, ale ogromna redukcja kodu JS, zwłaszcza że Apollo eliminuje potrzebę redukcji.
John Ottenlips