Integrieren von Django in Reactjs mithilfe des Django REST Framework
In diesem Artikel lernen wir den Prozess der Kommunikation zwischen dem Django-Backend und dem React js-Frontend mithilfe des Django-REST-Frameworks kennen. Zum besseren Verständnis des Konzepts werden wir einen Simple Task Manager erstellen und die primären Konzepte für diese Art der Integration zwischen React js und Django durchgehen.
Reactjs ist kurz gesagt eine Javascript-Bibliothek zur Entwicklung von Single Page Applications (SPA) mit sehr detaillierter und gut strukturierter Dokumentation . Für dieses Projekt wird React als Frontend dienen und die Benutzeroberfläche (UI) über die Requests an das Backend von Django handhaben.
Projektübersicht:
Schauen wir uns zuerst an, was wir bauen werden. Die folgenden Bilder zeigen die Benutzeroberfläche des Task-Managers.
Diese Task-Manager-Anwendung ist eine Art Aufgabenliste. Hier haben wir drei Schaltflächen wie „Abgeschlossen“, „Unvollständig“ und eine Schaltfläche zum Hinzufügen der Aufgabe mit dem Namen „Aufgabe hinzufügen“, wie im obigen Bild gezeigt.
Um eine Aufgabe hinzuzufügen, klicken Sie auf die Schaltfläche Aufgabe hinzufügen, wodurch ein Fenster in der App geöffnet wird, um die Aufgabe wie unten gezeigt hinzuzufügen. Hier können wir den „Titel“ für die Aufgabe hinzufügen und ihr im Abschnitt „Beschreibung“ eine Beschreibung geben. Schließlich können Sie je nach Status der Aufgabe (z. B. Abgeschlossen oder Unvollständig) ein Häkchen setzen oder das Häkchen entfernen, wie im folgenden Bild gezeigt:
Nachdem Sie die Aufgabe „gespeichert“ haben, können Sie zwischen den Registerkarten „Erledigt“ und „Unvollständig“ navigieren, um die Aufgaben wie unten gezeigt zu verfolgen:
Hier haben Sie auch die Möglichkeit, eine bestehende Aufgabe zu „löschen“ oder zu „bearbeiten“, wie unten gezeigt:
Alle oben ausgeführten Operationen werden vom Django REST Framework verwaltet.
Projektaufbau:
Voraussetzungen:
Die Voraussetzungen für das Projekt sind also:
Um zu überprüfen, ob Sie Python 3 installiert haben, verwenden Sie den folgenden Befehl in Ihrer Eingabeaufforderung (Da dieses Projekt auf einem Windows-Computer entwickelt wird, verwenden wir die Eingabeaufforderung, aber abhängig von Ihrem Betriebssystem können Sie das Terminal verwenden):
python -V
Dadurch wird die aktuelle Python-Version auf Ihrem System angezeigt, wie unten gezeigt:
Verwenden Sie den folgenden Befehl, um zu überprüfen, ob das Node-Modul installiert ist:
node --version
Dies zeigt Ihnen die Nodeversion auf Ihrem System wie unten gezeigt:
An diesem Punkt können wir loslegen, da wir Python und Node js in unserem System installiert haben.
Implementierung:
Beginnen wir mit dem Backend.
Backend (Django):
Öffnen wir nun unsere Eingabeaufforderung. Befolgen Sie nun die folgenden Schritte in der gleichen Reihenfolge, um diesem Artikel zu folgen.
Schritt 1: Erstellen Sie ein Verzeichnis namens „django-react-app“ mit dem folgenden Befehl (der Befehl kann sich je nach Betriebssystem leicht ändern):
mkdir django-react-app
Schritt 2: Mit dem folgenden Befehl in das Verzeichnis verschoben, das wir gerade erstellt haben:
cd django-react-project
Schritt 3: Erstellen Sie nun eine virtuelle Umgebung mit dem folgenden Befehl:
python -m venv dar
Wir haben unsere virtuelle Umgebung „dar“ genannt , kurz für Django und React. Dies ist notwendig, da wir Pakete und Abhängigkeiten nicht global installieren müssen. Es ist auch eine gute Programmierpraxis.
Schritt 4: Aktivieren Sie die virtuelle Umgebung, die wir gerade erstellt haben, mit dem folgenden Befehl:
dar\Scripts\activate.bat
Dadurch wird unsere virtuelle Maschine wie unten gezeigt aktiviert:
Schritt 5: Installieren Sie nun Django in der virtuellen Maschine mit dem folgenden Befehl:
pip install django
Sie erhalten eine ähnliche Meldung, wenn Ihre Installation abgeschlossen ist:
Schritt 6: Lassen Sie uns nun unser Projekt namens „ backend“ für unser Django-Backend erstellen. Verwenden Sie dazu den folgenden Befehl:
django-admin startproject backend
Die django-react-app wird unser Hauptordner sein und darin werden wir zwei Ordner haben, einen für das Backend und einen für das Frontend, die wir später erstellen werden.
Schritt 7: Navigieren Sie nun mit dem folgenden Befehl zum Backend-Ordner:
cd backend
Schritt 8: Jetzt starten wir unsere App und nennen sie „todo“ mit dem folgenden Befehl:
python manage.py startapp todo
Die App wird mit dem obigen Befehl wie unten gezeigt erstellt:
Lassen Sie uns jetzt fortfahren und den VS-Code starten und den darin enthaltenen Projektordner öffnen. In dieser Phase sieht unsere Projektstruktur wie folgt aus:
Schritt 9: Verwenden Sie nun den folgenden Befehl, um das Projekt zu migrieren:
python manage.py migrate
Die Migrationen werden wie unten gezeigt angewendet:
Schritt 10: Lassen Sie uns nun den Server mit dem folgenden Befehl ausführen:
python manage.py runserver
Jetzt können Sie den localhost besuchen , um zu überprüfen, ob das Projekt ordnungsgemäß gestartet wurde. Wie Sie im folgenden Bild sehen können, ist das Projekt in Betrieb:
Schritt 11: Jetzt müssen wir einige Konfigurationsschritte in der Datei settings.py durchführen. Fügen Sie im Abschnitt INSTALLED_APPS den Namen der App hinzu, die wir erstellt haben (z. B. todo), wie unten gezeigt:
Python3
# Application definition INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'todo', ]
Zu diesem Zeitpunkt würde die Datei settings.py wie folgt aussehen:
Python3
from pathlib import Path # Build paths inside the project like this: BASE_DIR / 'subdir'. BASE_DIR = Path(__file__).resolve().parent.parent # Quick-start development settings - unsuitable for production # See https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret! SECRET_KEY = 'django-insecure-_c3!4)8+yce2l-ju@gz@b6(e0$00y@xhx7+lxk1p==k+pyqko3' # SECURITY WARNING: don't run with debug turned on in production! DEBUG = True ALLOWED_HOSTS = [] # Application definition INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'todo', ] MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ] ROOT_URLCONF = 'backend.urls' TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, }, ] WSGI_APPLICATION = 'backend.wsgi.application' # Database # https://docs.djangoproject.com/en/3.2/ref/settings/#databases DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': BASE_DIR / 'db.sqlite3', } } # Password validation # https://docs.djangoproject.com/en/3.2/ref/settings/#auth-password-validators AUTH_PASSWORD_VALIDATORS = [ { 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', }, { 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', }, { 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', }, { 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', }, ] # Internationalization # https://docs.djangoproject.com/en/3.2/topics/i18n/ LANGUAGE_CODE = 'en-us' TIME_ZONE = 'UTC' USE_I18N = True USE_L10N = True USE_TZ = True # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/3.2/howto/static-files/ STATIC_URL = '/static/' # Default primary key field type # https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
Schritt 12: Als nächstes müssen wir ein Modell erstellen. Das Modell bestimmt, wie die ToDo - Elemente in der Datenbank gespeichert werden. Wir haben drei Eigenschaften im Modell:
- Titel: Dies ist der Titel der Aufgabe mit einer maximalen Länge von 150 Zeichen.
- Beschreibung: Dies ist die Beschreibung der Aufgabe mit einer maximalen Länge von 500 Zeichen.
- Abgeschlossen: Dies ist ein boolescher Wert, der verwendet wird, um den aktuellen Status der Aufgabe zu bestimmen. Standardmäßig wird es auf false gesetzt.
Öffnen Sie also die Datei "models.py " und den folgenden Code:
Python3
class Todo(models.Model): title=models.CharField(max_length=150) description=models.CharField(max_length=500) completed=models.BooleanField(default=False)
Wir werden auch eine Zeichenfolgendarstellung des Titels in der Todo-Klasse wie folgt erstellen:
Python3
def __str__(self): #it will return the title return self.title G")
Zu diesem Zeitpunkt sieht unsere Datei " models.py " folgendermaßen aus:
Python3
from django.db import models class Todo(models.Model): title=models.CharField(max_length=150) description=models.CharField(max_length=500) completed=models.BooleanField(default=False) # string representation of the class def __str__(self): #it will return the title return self.title
Schritt 13: Lassen Sie uns nun fortfahren und Migrationen durchführen. Beachten Sie, dass wir jedes Mal, wenn Sie Änderungen an der Datei "models.py " vornehmen, Migrationen vornehmen müssen. Verwenden Sie dazu den folgenden Befehl:
python manage.py makemigrations
Die folgende Nachricht wird generiert, wenn Ihre Migration fertig ist:
Schritt 14: Wenden wir nun alle Migrationen mit dem folgenden Befehl an:
python manage.py migrate
Dies wendet unsere Migrationen wie unten gezeigt an:
Jetzt können wir testen, ob die CRUD-Operationen mit der Todo-Modelldatei funktionieren, indem wir die Admin-Site (oder die Schnittstelle) verwenden. Dazu müssen wir die Modelle in der Datei admin.py registrieren .
Schritt 15: Öffnen Sie die Datei admin.py und fügen Sie den folgenden Code darin ein:
Python3
from django.contrib import admin # import the model Todo from .models import Todo # create a class for the admin-model integration class TodoAdmin(admin.ModelAdmin): # add the fields of the model here list_display = ("title","description","completed") # we will need to register the # model class and the Admin model class # using the register() method # of admin.site class admin.site.register(Todo,TodoAdmin)
Schritt 16: Jetzt erstellen wir einen Superuser mit dem folgenden Befehl:
python manage.py createsuperuser
Hier verwenden wir die folgenden Anmeldeinformationen:
- Benutzername: Geeks
- E-Mail-Adresse: geeks@geeksforgeeks.org
- Passwort: 12345
Hinweis: Sie können Ihre Anmeldeinformationen nach Bedarf einrichten. Die oben genannten Anmeldeinformationen müssen nicht identisch sein.
Wir würden die folgende Nachricht erhalten, wenn der Superuser erstellt wird:
Schritt 17: Lassen Sie uns nun den Server ausführen und überprüfen, ob alles wie vorgesehen läuft, indem Sie den folgenden Befehl verwenden:
python manage.p runserver
Navigieren Sie zu folgendem Link:
http://127.0.0.1:8000/admin/login/?next=/admin/
Dies zeigt uns die Admin-Seite wie unten gezeigt:
Geben Sie hier Ihre Anmeldeinformationen ein und melden Sie sich an. Wir verwenden die Anmeldeinformationen, die wir beim Erstellen des Superusers verwendet haben:
Dies führt uns auf die folgende Seite. Hier sehen wir unsere Benutzer, die App und die Gruppen wie unten gezeigt:
Benutzer:
Machen:
Lassen Sie uns eine Aufgabe hinzufügen und wie unten gezeigt speichern:
Wir können diese Aufgabe wie unten gezeigt im ToDo-Abschnitt sehen:
Erstellen der API:
Um die API zu erstellen, müssen wir das Django REST Framework für Serializer installieren. Wir müssen auch django-cors-headers für das Whitelisting von Port 3000 verwenden, der der Standardport für React ist.
Befolgen Sie nun die folgenden Schritte, um das Django-REST-Framework zu erstellen:
Schritt 1: Um das Django-REST-Framework zu installieren, verwenden Sie den folgenden Befehl im Backend-Verzeichnis:
pip install djangorestframework
Die folgende Meldung wird angezeigt, sobald die Installation abgeschlossen ist:
Schritt 2: Installieren Sie nun die django-cors-headers mit dem folgenden Befehl:
pip install django-cors-headers
Die folgende Meldung wird angezeigt, sobald die Installation abgeschlossen ist:
Schritt 3: Öffnen Sie nun die Datei setting.py und fügen Sie beide Abhängigkeiten, die wir gerade installiert haben, wie unten gezeigt zu INSTALLED_APPS hinzu:
Python3
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'todo', 'corsheaders', 'rest_framework', ]
Schritt 4: Auch in der Datei settings.py müssen wir den localhost-Port 3000 auf die Whitelist setzen. Wenn wir das nicht tun, wird es einen Block zwischen localhost:8000 und localhost:3000 geben. Fügen Sie den folgenden Code hinzu, um dasselbe zu erreichen:
Python3
# White listing the localhost:3000 port # for React CORS_ORIGIN_WHITELIST = ( 'http://localhost:3000' )
Schritt 5: Im Abschnitt MIDDLEWARE müssen wir die cors-headers-Einstellungen wie unten gezeigt hinzufügen:
Python3
MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', 'corsheaders.middleware.CorsMiddleware' ]
Zu diesem Zeitpunkt würde unsere settings.py wie folgt aussehen:
Python3
from pathlib import Path # Build paths inside the project like this: BASE_DIR / 'subdir'. BASE_DIR = Path(__file__).resolve().parent.parent # Quick-start development settings - unsuitable for production # See https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret! SECRET_KEY = 'django-insecure-_c3!4)8+yce2l-ju@gz@b6(e0$00y@xhx7+lxk1p==k+pyqko3' # SECURITY WARNING: don't run with debug turned on in production! DEBUG = True ALLOWED_HOSTS = [] # Application definition INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'todo', 'corsheaders', 'rest_framework', ] MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', 'corsheaders.middleware.CorsMiddleware' ] ROOT_URLCONF = 'backend.urls' TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, }, ] WSGI_APPLICATION = 'backend.wsgi.application' # Database # https://docs.djangoproject.com/en/3.2/ref/settings/#databases DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': BASE_DIR / 'db.sqlite3', } } # Password validation # https://docs.djangoproject.com/en/3.2/ref/settings/#auth-password-validators AUTH_PASSWORD_VALIDATORS = [ { 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', }, { 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', }, { 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', }, { 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', }, ] # White listing the localhost:3000 port CORS_ORIGIN_WHITELIST = ( 'http://localhost:3000' ) # Internationalization # https://docs.djangoproject.com/en/3.2/topics/i18n/ LANGUAGE_CODE = 'en-us' TIME_ZONE = 'UTC' USE_I18N = True USE_L10N = True USE_TZ = True # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/3.2/howto/static-files/ STATIC_URL = '/static/' # Default primary key field type # https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
Jetzt müssen wir die Sereilizer für das Todo-Datenmodell erstellen. Die Serilaizer sind dafür verantwortlich, dass Serializer Modellinstanzen für JSON erstellen. Dies hilft dem Frontend, mit den empfangenen Daten einfach zu arbeiten. JSON ist der Standard für den Datenaustausch im Web.
Schritt 6: Erstellen Sie nun eine Datei im todo-Ordner und nennen Sie sie serializers.py. Fügen Sie im Ordner den folgenden Code hinzu:
Python3
# import sereliazers from the REST framework from rest_framework import serializers # import the todo data model from .models import Todo # create a sereliazer class class TodoSerializer(serializers.ModelSerializer): # create a meta class class Meta: model = Todo fields = ('id', 'title','description','completed')
Schritt 7: Jetzt ist es an der Zeit, die Ansichten zu erstellen. Öffnen Sie also die Datei views.py . Fügen Sie nun den folgenden Code in die Datei ein:
Python3
from django.shortcuts import render # import view sets from the REST framework from rest_framework import viewsets # import the TodoSerializer from the serializer file from .serializers import TodoSerializer # import the Todo model from the models file from .models import Todo # create a class for the Todo model viewsets class TodoView(viewsets.ModelViewSet): # create a sereializer class and # assign it to the TodoSerializer class serializer_class = TodoSerializer # define a variable and populate it # with the Todo list objects queryset = Todo.objects.all()
Schritt 8: Öffnen Sie nun die Datei urls.py und fügen Sie den folgenden Code hinzu.
Python3
from django.contrib import admin # add include to the path from django.urls import path, include # import views from todo from todo import views # import routers from the REST framework # it is neccessary for routing from rest_framework import routers # create a router object router = routers.DefaultRouter() # register the router router.register(r'tasks',views.TodoView, 'task') urlpatterns = [ path('admin/', admin.site.urls), # add another path to the url patterns # when you visit the localhost:8000/api # you should be routed to the django Rest framework path('api/', include(router.urls)) ]
Dies ist der letzte Schritt zum Erstellen der REST-API, und wir können jetzt alle CRUD-Vorgänge ausführen. Router ermöglichen uns Abfragen. Wenn wir zum Beispiel zu den „Aufgaben“ gehen, wird die Liste aller Aufgaben zurückgegeben. Sie können auch eine einzelne "Aufgabe" mit einer ID haben , um eine einzelne Aufgabe zurückzugeben, wobei die ID der Primärschlüssel ist.
Lassen Sie uns nun prüfen, ob wir uns in die richtige Richtung bewegen. Führen Sie also den Server aus und navigieren Sie zur folgenden URL:
localhost:8000/api
Wenn alles in Ordnung ist, erhalten wir das folgende Ergebnis:
Wie Sie sehen können, ist unsere API in Betrieb.
Wenn wir nun zu den folgenden Links navigieren, können wir unsere Aufgaben anzeigen und mit ihnen interagieren:
locaLHOST:8000/api/tasks
Frontend (React js):
Lassen Sie uns nun das Frontend für unsere Todo-App erstellen. Führen Sie dazu die folgenden Schritte aus:
Schritt 1: Navigieren Sie zum Hauptprojektverzeichnis (dh django-react-app) und aktivieren Sie die virtuelle Umgebung mit dem folgenden Befehl:
dar\Scripts\activate.bat
Schritt 2: Verwenden Sie nun den folgenden Befehl, um eine Boilerplate der React js-App zu erstellen:
npx create-react-app frontend
Hier steht npx für Node Package Executable. Nachdem die Boilerplate eingerichtet ist, erhalten Sie die folgende Meldung:
Wir brauchen auch etwas UI-Flair für das UI-Design, insbesondere Reactstrap und Bootstrap.
Schritt 3: Verwenden Sie also den folgenden Befehl, um Reactstrap und Bootstrap im Projekt zu installieren:
npm install reactstrap bootstrap
Schritt 4: Wechseln Sie zuerst in den Frontend-Ordner und verwenden Sie den folgenden Befehl, um den React-Server auszuführen, um sicherzustellen, dass alles bis zu diesem Punkt funktioniert:
npm start
Wenn alles in Ordnung ist, erhalten Sie die folgende Seite auf localhost:3000
Schritt 5: Öffnen Sie nun die Datei App.js im Frontend-Ordner. Und löschen Sie den Boilerplate-Code und ändern Sie ihn in den folgenden Code:
Javascript
import "./App.css"; function App() { return <div className="App"><h2>Welcome to Geeksforgeeks!</h2></div>; } export default App;
An dieser Stelle sieht das Frontend wie folgt aus:
Wie Sie im obigen Bild sehen können. Alle an der App.js-Datei vorgenommenen Änderungen werden direkt in der Benutzeroberfläche wiedergegeben.
Schritt 6: Nun der Code zur App.js Datei. Kommentare werden dem Code zum besseren Verständnis hinzugefügt.
Javascript
// import Component from the react module import React, { Component } from "react"; import Modal from "./components/Modal"; import axios from 'axios'; // create a class that extends the component class App extends Component { // add a constructor to take props constructor(props) { super(props); // add the props here this.state = { // the viewCompleted prop represents the status // of the task. Set it to false by default viewCompleted: false, activeItem: { title: "", description: "", completed: false }, // this list stores all the completed tasks taskList: [] }; } // Add componentDidMount() componentDidMount() { this.refreshList(); } refreshList = () => { axios //Axios to send and receive HTTP requests .get("http://localhost:8000/api/tasks/") .then(res => this.setState({ taskList: res.data })) .catch(err => console.log(err)); }; // this arrow function takes status as a parameter // and changes the status of viewCompleted to true // if the status is true, else changes it to false displayCompleted = status => { if (status) { return this.setState({ viewCompleted: true }); } return this.setState({ viewCompleted: false }); }; // this array function renders two spans that help control // the set of items to be displayed(ie, completed or incomplete) renderTabList = () => { return ( <div className="my-5 tab-list"> <span onClick={() => this.displayCompleted(true)} className={this.state.viewCompleted ? "active" : ""} > completed </span> <span onClick={() => this.displayCompleted(false)} className={this.state.viewCompleted ? "" : "active"} > Incompleted </span> </div> ); }; // Main variable to render items on the screen renderItems = () => { const { viewCompleted } = this.state; const newItems = this.state.taskList.filter( (item) => item.completed === viewCompleted ); return newItems.map((item) => ( <li key={item.id} className="list-group-item d-flex justify-content-between align-items-center" > <span className={`todo-title mr-2 ${ this.state.viewCompleted ? "completed-todo" : "" }`} title={item.description} > {item.title} </span> <span> <button onClick={() => this.editItem(item)} className="btn btn-secondary mr-2" > Edit </button> <button onClick={() => this.handleDelete(item)} className="btn btn-danger" > Delete </button> </span> </li> )); }; toggle = () => { //add this after modal creation this.setState({ modal: !this.state.modal }); }; handleSubmit = (item) => { this.toggle(); alert("save" + JSON.stringify(item)); }; // Submit an item handleSubmit = (item) => { this.toggle(); if (item.id) { // if old post to edit and submit axios .put(`http://localhost:8000/api/tasks/${item.id}/`, item) .then((res) => this.refreshList()); return; } // if new post to submit axios .post("http://localhost:8000/api/tasks/", item) .then((res) => this.refreshList()); }; // Delete item handleDelete = (item) => { axios .delete(`http://localhost:8000/api/tasks/${item.id}/`) .then((res) => this.refreshList()); }; handleDelete = (item) => { alert("delete" + JSON.stringify(item)); }; // Create item createItem = () => { const item = { title: "", description: "", completed: false }; this.setState({ activeItem: item, modal: !this.state.modal }); }; //Edit item editItem = (item) => { this.setState({ activeItem: item, modal: !this.state.modal }); }; // Start by visual effects to viewer render() { return ( <main className="content"> <h1 className="text-success text-uppercase text-center my-4"> GFG Task Manager </h1> <div className="row "> <div className="col-md-6 col-sm-10 mx-auto p-0"> <div className="card p-3"> <div className=""> <button onClick={this.createItem} className="btn btn-info"> Add task </button> </div> {this.renderTabList()} <ul className="list-group list-group-flush"> {this.renderItems()} </ul> </div> </div> </div> {this.state.modal ? ( <Modal activeItem={this.state.activeItem} toggle={this.toggle} onSave={this.handleSubmit} /> ) : null} </main> ); } } export default App;
Schritt 7: Öffnen Sie nun die Datei Index.css , löschen Sie das darin enthaltene CSS und fügen Sie das folgende CSS in die Datei ein:
CSS
.todo-title { cursor: pointer; } .completed-todo { text-decoration: line-through; } .tab-list > span { padding: 5px 8px; border: 1px solid rgb(7, 167, 68); border-radius: 10px; margin-right: 5px; cursor: pointer; } .tab-list > span.active { background-color: rgb(6, 139, 12); color: #fff; }
Schritt 8: Erstellen Sie nun im src -Verzeichnis einen neuen Ordner mit dem Namen „Components“ und fügen Sie eine Datei Modal.js hinzu. Fügen Sie dann den folgenden Code hinzu.
Javascript
import React, { Component } from "react"; // importing all of these classes from reactstrap module import { Button, Modal, ModalHeader, ModalBody, ModalFooter, Form, FormGroup, Input, Label } from "reactstrap"; // build a class base component class CustomModal extends Component { constructor(props) { super(props); this.state = { activeItem: this.props.activeItem }; } // changes handler to check if a checkbox is checed or not handleChange = e => { let { name, value } = e.target; if (e.target.type === "checkbox") { value = e.target.checked; } const activeItem = { ...this.state.activeItem, [name]: value }; this.setState({ activeItem }); }; // rendering modal in the custommodal class received toggle and on save as props, render() { const { toggle, onSave } = this.props; return ( <Modal isOpen={true} toggle={toggle}> <ModalHeader toggle={toggle}> Task Item </ModalHeader> <ModalBody> <Form> {/* 3 formgroups 1 title label */} <FormGroup> <Label for="title">Title</Label> <Input type="text" name="title" value={this.state.activeItem.title} onChange={this.handleChange} placeholder="Enter Task Title" /> </FormGroup> {/* 2 description label */} <FormGroup> <Label for="description">Description</Label> <Input type="text" name="description" value={this.state.activeItem.description} onChange={this.handleChange} placeholder="Enter Task Description" /> </FormGroup> {/* 3 completed label */} <FormGroup check> <Label for="completed"> <Input type="checkbox" name="completed" checked={this.state.activeItem.completed} onChange={this.handleChange} /> Completed </Label> </FormGroup> </Form> </ModalBody> {/* create a modal footer */} <ModalFooter> <Button color="success" onClick={() => onSave(this.state.activeItem)}> Save </Button> </ModalFooter> </Modal> ); } } export default CustomModal
Schritt 10: Nehmen Sie die Änderungen an der Datei index.js wie folgt vor:
Javascript
import React from "react"; import ReactDOM from "react-dom"; import "./index.css"; import App from "./App"; // importing css stylesheet to use the bootstrap class // add this line only in this file import "bootstrap/dist/css/bootstrap.min.css"; ReactDOM.render( <React.StrictMode> <App /> </React.StrictMode>, document.getElementById("root") );
API-Verbindung:
Damit wir Requestsn an die API-Endpunkte auf dem Backend-Server von Django stellen können, müssen wir Axios installieren. Verwenden Sie den folgenden Befehl im Frontend-Ordner, um Axios zu installieren:
npm install axios
Ausgabe:
Gratulation!!. An diesem Punkt haben Sie erfolgreich eine Fullstack Django-React-App erstellt und das Django-REST-Framework verwendet, um die Kommunikation zwischen Frontend und Backend herzustellen.