Erstellen einer modernen Webanwendung zum Verwalten von Kundeninformationen mit Django und Reagieren auf Ubuntu 18.04

Der Autor hatOpen Sourcing Mental Illness Ltd ausgewählt, um eine Spende im Rahmen desWrite for DOnations-Programms zu erhalten.

Einführung

Die Benutzer verwenden verschiedene Arten von Geräten, um eine Verbindung zum Internet herzustellen und im Internet zu surfen. Aus diesem Grund müssen Anwendungen von verschiedenen Standorten aus zugänglich sein. Für herkömmliche Websites reicht in der Regel eine ansprechende Benutzeroberfläche aus, komplexere Anwendungen erfordern jedoch häufig die Verwendung anderer Techniken und Architekturen. Dazu gehören separate REST-Back-End- und Front-End-Anwendungen, die als clientseitige Webanwendungen, Progressive Web Apps (PWAs) oder native mobile Apps implementiert werden können.

Einige Tools, die Sie beim Erstellen komplexerer Anwendungen verwenden können, umfassen:

  • React, ein JavaScript-Framework, mit dem Entwickler Web- und native Frontends für ihre REST-API-Backends erstellen können.

  • Django, ein kostenloses und Open-Source-Python-Webframework, das dem Softwarearchitekturmuster vonmodel view controller (MVC)folgt.

  • Django REST framework, ein leistungsstarkes und flexibles Toolkit zum Erstellen von REST-APIs in Django.

In diesem Tutorial erstellen Sie eine moderne Webanwendung mit einem separaten REST-API-Backend und Frontend unter Verwendung von React, Django und dem Django-REST-Framework. Mit React with Django können Sie von den neuesten Fortschritten in der JavaScript- und Front-End-Entwicklung profitieren. Anstatt eine Django-Anwendung zu erstellen, die eine integrierte Template-Engine verwendet, verwenden Sie React als UI-Bibliothek und nutzen dabei das virtuelle Document Object Model (DOM), den deklarativen Ansatz und Komponenten, mit denen sich Daten schnell ändern lassen.

In der Webanwendung, die Sie erstellen, werden Datensätze zu Kunden in einer Datenbank gespeichert, und Sie können sie als Ausgangspunkt für eine CRM-Anwendung verwenden. Wenn Sie fertig sind, können Sie Datensätze mithilfe einer mitBootstrap 4 gestalteten React-Oberfläche erstellen, lesen, aktualisieren und löschen.

Voraussetzungen

Um dieses Tutorial abzuschließen, benötigen Sie:

[[Schritt-1 - Erstellen einer Python-virtuellen Umgebung und Installieren von Abhängigkeiten] == Schritt 1 - Erstellen einer virtuellen Python-Umgebung und Installieren von Abhängigkeiten

In diesem Schritt erstellen wir eine virtuelle Umgebung und installieren die erforderlichen Abhängigkeiten für unsere Anwendung, einschließlich Django, des Django REST-Frameworks unddjango-cors-headers.

Unsere Anwendung verwendet zwei verschiedene Entwicklungsserver für Django und React. Sie werden auf verschiedenen Ports ausgeführt und fungieren als zwei separate Domänen. Aus diesem Grund müssen wircross-origin resource sharing (CORS) aktivieren, um HTTP-Anforderungen von React an Django zu senden, ohne vom Browser blockiert zu werden.

Navigieren Sie zu Ihrem Ausgangsverzeichnis und erstellen Sie eine virtuelle Umgebung mit dem Python 3-Modul vonvenv:

cd ~
python3 -m venv ./env

Aktivieren Sie die erstellte virtuelle Umgebung mitsource:

source env/bin/activate

Installieren Sie als Nächstes die Abhängigkeiten des Projekts mitpip. Dazu gehören:

  • Django: Das Webframework für das Projekt.

  • Django REST framework: Eine Drittanbieteranwendung, die REST-APIs mit Django erstellt.

  • django-cors-headers: Ein Paket, das CORS aktiviert.

Installieren Sie das Django-Framework:

pip install django djangorestframework django-cors-headers

Mit den installierten Projektabhängigkeiten können Sie das Django-Projekt und das React-Frontend erstellen.

[[Schritt 2 - Erstellen des Django-Projekts]] == Schritt 2 - Erstellen des Django-Projekts

In diesem Schritt generieren wir das Django-Projekt mit den folgenden Befehlen und Dienstprogrammen:

  • django-admin startproject project-name:django-admin ist ein Befehlszeilenprogramm, mit dem Aufgaben mit Django ausgeführt werden. Der Befehlstartprojecterstellt ein neues Django-Projekt.

  • python manage.py startapp myapp:manage.py ist ein Dienstprogramm-Skript, das automatisch zu jedem Django-Projekt hinzugefügt wird und eine Reihe von Verwaltungsaufgaben ausführt: Erstellen neuer Anwendungen, Migrieren der Datenbank und lokales Bereitstellen des Django-Projekts. Der Befehlstartapperstellt eine Django-Anwendung innerhalb des Django-Projekts. In Django beschreibt der Begriffapplication ein Python-Paket, das einige Funktionen in einem Projekt bereitstellt.

Erstellen Sie zunächst das Django-Projekt mitdjango-admin startproject. Wir werden unser Projektdjangoreactproject nennen:

django-admin startproject djangoreactproject

Bevor wir fortfahren, schauen wir uns die Verzeichnisstruktur unseres Django-Projekts mit dem Befehltreean.

[.Hinweis]##

Tip:tree ist ein nützlicher Befehl zum Anzeigen von Datei- und Verzeichnisstrukturen über die Befehlszeile. Sie können es mit dem folgenden Befehl installieren:

sudo apt-get install tree

Um es zu verwenden, geben Siecd in das gewünschte Verzeichnis ein und geben Sietree ein oder geben Sie den Pfad zum Startpunkt mittree /home/sammy/sammys-project.
an

Navigieren Sie zum Ordnerdjangoreactproject in Ihrem Projektstamm und führen Sie den Befehltree aus:

cd ~/djangoreactproject
tree

Sie werden die folgende Ausgabe sehen:

Output├── djangoreactproject
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
└── manage.py

Der Ordner~/djangoreactprojectist das Stammverzeichnis des Projekts. In diesem Ordner befinden sich mehrere Dateien, die für Ihre Arbeit wichtig sind:

  • manage.py: Das Dienstprogramm-Skript, das eine Reihe von Verwaltungsaufgaben ausführt.

  • settings.py: Die Hauptkonfigurationsdatei für das Django-Projekt, in der Sie die Projekteinstellungen ändern können. Diese Einstellungen umfassen Variablen wieINSTALLED_APPS,list von Zeichenfolgen, die die aktivierten Anwendungen für Ihr Projekt festlegen. Die Django-Dokumentation enthält weitere Informationen zuavailable settings.

  • urls.py: Diese Datei enthält eine Liste von URL-Mustern und verwandten Ansichten. Jedes Muster ordnet eine Verbindung zwischen einer URL und der Funktion zu, die für diese URL aufgerufen werden soll. Weitere Informationen zu URLs und Ansichten finden Sie in unserem Tutorial zuHow To Create Django Views.

Unser erster Schritt bei der Arbeit mit dem Projekt besteht darin, die im vorherigen Schritt installierten Pakete, einschließlich des Django REST-Frameworks und des Django CORS-Pakets, zu konfigurieren, indem Sie sie zusettings.py hinzufügen. Öffnen Sie die Datei mitnano oder Ihrem bevorzugten Editor:

nano ~/djangoreactproject/djangoreactproject/settings.py

Navigieren Sie zur EinstellungINSTALLED_APPS und fügen Sie die Anwendungenrest_framework undcorsheaders am Ende der Liste hinzu:

~/djangoreactproject/djangoreactproject/settings.py

...
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework',
    'corsheaders'
]

Fügen Sie als Nächstes die Middlewarecorsheaders.middleware.CorsMiddlewareaus dem zuvor installierten CORS-Paket zur EinstellungMIDDLEWAREhinzu. Diese Einstellung ist eine Liste vonmiddlewares, einer Python-Klasse, die Code enthält, der jedes Mal verarbeitet wird, wenn Ihre Webanwendung eine Anforderung oder Antwort verarbeitet:

~/djangoreactproject/djangoreactproject/settings.py

...

MIDDLEWARE = [
...
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'corsheaders.middleware.CorsMiddleware'
]

Als Nächstes können Sie CORS aktivieren. Die EinstellungCORS_ORIGIN_ALLOW_ALL gibt an, ob Sie CORS für alle Domänen zulassen möchten oder nicht, undCORS_ORIGIN_WHITELIST ist ein Python-Tupel, das zulässige URLs enthält. In unserem Fall fügen wir unserersettings.py-Datei neue Einstellungen fürCORS_ORIGIN_ALLOW_ALL = False undCORS_ORIGIN_WHITELIST('localhost:3000',)hinzu, da der React-Entwicklungsserver mithttp://localhost:3000 ausgeführt wird. Fügen Sie diese Einstellungen an einer beliebigen Stelle in der Datei hinzu:

~/djangoreactproject/djangoreactproject/settings.py

...
CORS_ORIGIN_ALLOW_ALL = False

CORS_ORIGIN_WHITELIST = (
       'localhost:3000',
)
...

Weitere Konfigurationsoptionen finden Sie indjango-cors-headers docs.

Speichern Sie die Datei und beenden Sie den Editor, wenn Sie fertig sind.

Erstellen Sie noch im Verzeichnis~/djangoreactproject eine neue Django-Anwendung mit dem Namencustomers:

python manage.py startapp customers

Dies enthält diemodels undviews für die Verwaltung von Kunden. Modelle definieren die Felder und das Verhalten unserer Anwendungsdaten, während Ansichten es unserer Anwendung ermöglichen, Webanforderungen ordnungsgemäß zu verarbeiten und die erforderlichen Antworten zurückzugeben.

Fügen Sie diese Anwendung als Nächstes zur Liste der installierten Anwendungen in dersettings.py-Datei Ihres Projekts hinzu, damit Django sie als Teil des Projekts erkennt. Öffnen Siesettings.py erneut:

nano ~/djangoreactproject/djangoreactproject/settings.py

Fügen Sie die Anwendungcustomershinzu:

~/djangoreactproject/djangoreactproject/settings.py

...
INSTALLED_APPS = [
    ...
    'rest_framework',
    'corsheaders',
    'customers'
]
...

Als nächstes wirdmigratein der Datenbank gespeichert und der lokale Entwicklungsserver gestartet. Migrations sind Djangos Methode, die Änderungen, die Sie an Ihren Modellen vornehmen, in Ihr Datenbankschema zu übertragen. Diese Änderungen können beispielsweise das Hinzufügen eines Felds oder das Löschen eines Modells umfassen. Weitere Informationen zu Modellen und Migrationen finden Sie unterHow To Create Django Models.

Migrieren Sie die Datenbank:

python manage.py migrate

Starten Sie den lokalen Entwicklungsserver:

python manage.py runserver

Sie sehen eine Ausgabe ähnlich der folgenden:

OutputPerforming system checks...

System check identified no issues (0 silenced).
October 22, 2018 - 15:14:50
Django version 2.1.2, using settings 'djangoreactproject.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

Ihre Webanwendung wird abhttp://127.0.0.1:8000 ausgeführt. Wenn Sie in Ihrem Webbrowser zu dieser Adresse navigieren, sollte die folgende Seite angezeigt werden:

Django demo page

Lassen Sie zu diesem Zeitpunkt die Anwendung aktiv und öffnen Sie ein neues Terminal, um das Projekt weiterzuentwickeln.

[[Schritt 3 - Erstellen des Reaktions-Frontends]] == Schritt 3 - Erstellen des Reaktions-Frontends

In diesem Abschnitt erstellen wir die Front-End-Anwendung unseres Projekts mit React.

React verfügt über ein offizielles Dienstprogramm, mit dem Sie schnell React-Projekte generieren können, ohneWebpack direkt konfigurieren zu müssen. Webpack ist ein Modulbündler, mit dem Web-Assets wie JavaScript-Code, CSS und Bilder gebündelt werden. Bevor Sie Webpack verwenden können, müssen Sie normalerweise verschiedene Konfigurationsoptionen festlegen. Dank des Dienstprogrammscreate-react-appmüssen Sie sich jedoch nicht direkt mit Webpack befassen, bis Sie entscheiden, dass Sie mehr Kontrolle benötigen. Umcreate-react-app auszuführen, können Sienpx verwenden, ein Tool, das die Paket-Binärdateien vonnpmausführt.

Stellen Sie in Ihrem zweiten Terminal sicher, dass Sie sich in Ihrem Projektverzeichnis befinden:

cd ~/djangoreactproject

Erstellen Sie ein React-Projekt mit dem Namenfrontend mitcreate-react-app undnpx:

npx create-react-app frontend

Navigieren Sie als Nächstes in Ihrer React-Anwendung und starten Sie den Entwicklungsserver:

cd ~/djangoreactproject/frontend
npm start

Ihre Anwendung wird vonhttp://localhost:3000/ ausgeführt:

React demo page

Lassen Sie den React-Entwicklungsserver aktiv und öffnen Sie ein anderes Terminalfenster, um fortzufahren.

Um die Verzeichnisstruktur des gesamten Projekts zu diesem Zeitpunkt anzuzeigen, navigieren Sie zum Stammordner und führen Sietree erneut aus:

cd ~/djangoreactproject
tree

Sie sehen eine Struktur wie diese:

Output├── customers
│   ├── admin.py
│   ├── apps.py
│   ├── __init__.py
│   ├── migrations
│   │   └── __init__.py
│   ├── models.py
│   ├── tests.py
│   └── views.py
├── djangoreactproject
│   ├── __init__.py
│   ├── __pycache__
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── frontend
│   ├── package.json
│   ├── public
│   │   ├── favicon.ico
│   │   ├── index.html
│   │   └── manifest.json
│   ├── README.md
│   ├── src
│   │   ├── App.css
│   │   ├── App.js
│   │   ├── App.test.js
│   │   ├── index.css
│   │   ├── index.js
│   │   ├── logo.svg
│   │   └── registerServiceWorker.js
│   └── yarn.lock
└── manage.py

Unsere Anwendung verwendet Bootstrap 4, um die React-Oberfläche zu formatieren, sodass wir sie in die Dateifrontend/src/App.cssaufnehmen, die unsere CSS-Einstellungen verwaltet. Öffne die Datei:

nano ~/djangoreactproject/frontend/src/App.css

Fügen Sie am Anfang der Datei die folgendenimport hinzu. Sie können den vorhandenen Inhalt der Datei löschen. Dies ist jedoch nicht erforderlich:

~/djangoreactproject/frontend/src/App.css

@import  'https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css';

Hier ist@import eine CSS-Anweisung, mit der Stilregeln aus anderen Stylesheets importiert werden.

Nachdem wir sowohl die Back-End- als auch die Front-End-Anwendung erstellt haben, erstellen wir das Kundenmodell und einige Demo-Daten.

[[Schritt 4 - Erstellen des Kundenmodells und der Anfangsdaten] == Schritt 4 - Erstellen des Kundenmodells und der Anfangsdaten

Nach dem Erstellen der Django-Anwendung und des React-Frontends erstellen wir als Nächstes das Kundenmodell, das die Datenbanktabelle darstellt, die Informationen zu Kunden enthält. Sie benötigen kein SQL, da die DjangoObject Relational Mapper (ORM) Datenbankoperationen ausführen, indem sie Python-Klassen und -Variablen SQL-Tabellen und -Spalten zuordnen. Auf diese Weise abstrahiert der Django ORM SQL-Interaktionen mit der Datenbank über eine Python-Schnittstelle.

Aktivieren Sie Ihre virtuelle Umgebung erneut:

cd ~
source env/bin/activate

Wechseln Sie in das Verzeichniscustomers und öffnen Siemodels.py, eine Python-Datei, die die Modelle Ihrer Anwendung enthält:

cd ~/djangoreactproject/customers/
nano models.py

Die Datei enthält den folgenden Inhalt:

~/djangoreactproject/customers/models.py

from django.db import models
# Create your models here.

Die API des Kundenmodells ist dank der Importanweisung vonfrom django.db import modelsbereits in die Datei importiert. Sie fügen nun die KlasseCustomer hinzu, diemodels.Model erweitert. Jedes Modell in Django ist eine Python-Klasse, diedjango.db.models.Model erweitert.

DasCustomer-Modell verfügt über folgende Datenbankfelder:

  • first_name - Der Vorname des Kunden.

  • last_name - Der Nachname des Kunden.

  • email - Die E-Mail-Adresse des Kunden.

  • phone - Die Telefonnummer des Kunden.

  • address - Die Adresse des Kunden.

  • description - Die Beschreibung des Kunden.

  • createdAt - Das Datum, an dem der Kunde hinzugefügt wird.

Wir werden auch die Funktion__str__()hinzufügen, die definiert, wie das Modell angezeigt wird. In unserem Fall ist dies der Vorname des Kunden. Weitere Informationen zum Erstellen von Klassen und Definieren von Objekten finden Sie unterHow To Construct Classes and Define Objects in Python 3.

Fügen Sie der Datei den folgenden Code hinzu:

~/djangoreactproject/customers/models.py

from django.db import models

class Customer(models.Model):
    first_name = models.CharField("First name", max_length=255)
    last_name = models.CharField("Last name", max_length=255)
    email = models.EmailField()
    phone = models.CharField(max_length=20)
    address =  models.TextField(blank=True, null=True)
    description = models.TextField(blank=True, null=True)
    createdAt = models.DateTimeField("Created At", auto_now_add=True)

    def __str__(self):
        return self.first_name

Migrieren Sie als Nächstes die Datenbank, um die Datenbanktabellen zu erstellen. Der Befehlmakemigrations erstellt die Migrationsdateien, in denen Modelländerungen hinzugefügt werden, undmigrate wendet die Änderungen in den Migrationsdateien auf die Datenbank an.

Navigieren Sie zurück zum Stammverzeichnis des Projekts:

cd ~/djangoreactproject

Führen Sie Folgendes aus, um die Migrationsdateien zu erstellen:

python manage.py makemigrations

Sie erhalten eine Ausgabe, die folgendermaßen aussieht:

Outputcustomers/migrations/0001_initial.py
    - Create model Customer

Übernehmen Sie diese Änderungen in die Datenbank:

python manage.py migrate

Die Ausgabe zeigt eine erfolgreiche Migration an:

OutputOperations to perform:
  Apply all migrations: admin, auth, contenttypes, customers, sessions
Running migrations:
  Applying customers.0001_initial... OK

Als Nächstes verwenden Siedata migration file, um erste Kundendaten zu erstellen. Eindata migration file ist eine Migration, die Daten in der Datenbank hinzufügt oder ändert. Erstellen Sie eine leere Datenmigrationsdatei für die Anwendungcustomers:

python manage.py makemigrations --empty --name customers customers

Sie sehen die folgende Bestätigung mit dem Namen Ihrer Migrationsdatei:

OutputMigrations for 'customers':
  customers/migrations/0002_customers.py

Beachten Sie, dass der Name Ihrer Migrationsdatei0002_customers.py lautet.

Navigieren Sie als Nächstes im Migrationsordner der Anwendungcustomers:

cd ~/djangoreactproject/customers/migrations

Öffnen Sie die erstellte Migrationsdatei:

nano 0002_customers.py

Dies ist der ursprüngliche Inhalt der Datei:

~/djangoreactproject/customers/migrations/0002_customers.py

from django.db import migrations

class Migration(migrations.Migration):
    dependencies = [
        ('customers', '0001_initial'),
    ]
    operations = [
    ]

Die import-Anweisung importiert diemigrations-API, eine Django-API zum Erstellen von Migrationen, ausdjango.db, einem integrierten Paket, das Klassen für die Arbeit mit Datenbanken enthält.

Die KlasseMigration ist eine Python-Klasse, die die Vorgänge beschreibt, die beim Migrieren von Datenbanken ausgeführt werden. Diese Klasse erweitertmigrations.Migration und hat zwei Listen:

  • dependencies: Enthält die abhängigen Migrationen.

  • operations: Enthält die Vorgänge, die ausgeführt werden, wenn die Migration angewendet wird.

Fügen Sie als Nächstes einmethod hinzu, um Demo-Kundendaten zu erstellen. Fügen Sie vor der Definition der KlasseMigrationdie folgende Methode hinzu:

~/djangoreactproject/customers/migrations/0002_customers.py

...
def create_data(apps, schema_editor):
    Customer = apps.get_model('customers', 'Customer')
    Customer(first_name="Customer 001", last_name="Customer 001", email="[email protected]", phone="00000000", address="Customer 000 Address", description= "Customer 001 description").save()

...

Bei dieser Methode greifen wir auf dieCustomer-Klasse unserercustomers-App zu und erstellen einen Demo-Kunden, der in die Datenbank eingefügt werden soll.

Um die KlasseCustomerzu erhalten, mit der neue Kunden erstellt werden können, verwenden wir die Methodeget_model()des Objektsapps. Dasapps-Objekt repräsentiert dieregistry der installierten Anwendungen und ihrer Datenbankmodelle.

Dasapps-Objekt wird von derRunPython()-Methode übergeben, wenn wir damitcreate_data() ausführen. Fügen Sie die Methodemigrations.RunPython() zur leeren Listeoperationshinzu:

~/djangoreactproject/customers/migrations/0002_customers.py

...
    operations = [
        migrations.RunPython(create_data),
    ]

RunPython() ist Teil der Migrations-API, mit der Sie benutzerdefinierten Python-Code in einer Migration ausführen können. Unsereoperations-Liste gibt an, dass diese Methode ausgeführt wird, wenn wir die Migration anwenden.

Dies ist die komplette Datei:

~/djangoreactproject/customers/migrations/0002_customers.py

from django.db import migrations

def create_data(apps, schema_editor):
    Customer = apps.get_model('customers', 'Customer')
    Customer(first_name="Customer 001", last_name="Customer 001", email="[email protected]", phone="00000000", address="Customer 000 Address", description= "Customer 001 description").save()

class Migration(migrations.Migration):
    dependencies = [
        ('customers', '0001_initial'),
    ]
    operations = [
        migrations.RunPython(create_data),
    ]

Weitere Informationen zu Datenmigrationen finden Sie in der Dokumentation zudata migrations in Django

Um Ihre Datenbank zu migrieren, navigieren Sie zunächst zurück zum Stammordner Ihres Projekts:

cd ~/djangoreactproject

Migrieren Sie Ihre Datenbank, um die Demo-Daten zu erstellen:

python manage.py migrate

Sie sehen eine Ausgabe, die die Migration bestätigt:

OutputOperations to perform:
  Apply all migrations: admin, auth, contenttypes, customers, sessions
Running migrations:
  Applying customers.0002_customers... OK

Weitere Informationen zu diesem Vorgang finden Sie unterHow To Create Django Models.

Nachdem das Kundenmodell und die Demo-Daten erstellt wurden, können wir mit der Erstellung der REST-API fortfahren.

[[Schritt-5 -—- Erstellen der Rest-API]] == Schritt 5 - Erstellen der REST-API

In diesem Schritt erstellen wir die REST-API mit dem Django-REST-Framework. Wir erstellen verschiedeneAPI views. Eine API-Ansicht ist eine Funktion, die eine API-Anforderung oder einen API-Aufruf verarbeitet, währendAPI endpoint eine eindeutige URL ist, die einen Berührungspunkt mit dem REST-System darstellt. Wenn der Benutzer beispielsweise eine GET-Anfrage an einen API-Endpunkt sendet, ruft Django die entsprechende Funktion oder API-Ansicht auf, um die Anfrage zu bearbeiten und mögliche Ergebnisse zurückzugeben.

Wir werden auchserializers verwenden. Mit Aserializer im Django REST Framework können komplexe Modellinstanzen und QuerySets für den API-Verbrauch in das JSON-Format konvertiert werden. Die Serializer-Klasse kann auch in die andere Richtung arbeiten und Mechanismen zum Parsen und Deserialisieren von Daten in Django-Modelle und QuerySets bereitstellen.

Unsere API-Endpunkte umfassen:

  • api/customers: Dieser Endpunkt wird verwendet, um Kunden zu erstellen und paginierte Kundengruppen zurückzugeben.

  • api/customers/<pk>: Dieser Endpunkt wird verwendet, um einzelne Kunden nach Primärschlüssel oder ID abzurufen, zu aktualisieren und zu löschen.

Wir erstellen auch URLs in derurls.py-Datei des Projekts für die entsprechenden Endpunkte (d. H.api/customers undapi/customers/<pk>).

Beginnen wir mit der Erstellung derserializer class für unserCustomer-Modell.

Hinzufügen der Serializer-Klasse

Das Erstellen einer Serializer-Klasse für unserCustomer-Modell ist erforderlich, um Kundeninstanzen und QuerySets von und nach JSON zu transformieren. Um die Serializer-Klasse zu erstellen, erstellen Sie zunächst eineserializers.py-Datei in dercustomers-Anwendung:

cd ~/djangoreactproject/customers/
nano serializers.py

Fügen Sie den folgenden Code hinzu, um die Serializer-API und das Modell vonCustomerzu importieren:

~/djangoreactproject/customers/serializers.py

from rest_framework import serializers
from .models import Customer

Erstellen Sie als Nächstes eine Serializer-Klasse, dieserializers.ModelSerializer erweitert und die Felder angibt, die serialisiert werden sollen:

~/djangoreactproject/customers/serializers.py

...
class CustomerSerializer(serializers.ModelSerializer):

    class Meta:
        model = Customer
        fields = ('pk','first_name', 'last_name', 'email', 'phone','address','description')

Die KlasseMeta gibt das Modell und die zu serialisierenden Felder an:pk,first_name,last_name,email,phone,address description.

Dies ist der vollständige Inhalt der Datei:

~/djangoreactproject/customers/serializers.py

from rest_framework import serializers
from .models import Customer

class CustomerSerializer(serializers.ModelSerializer):

    class Meta:
        model = Customer
        fields = ('pk','first_name', 'last_name', 'email', 'phone','address','description')

Nachdem wir unsere Serializer-Klasse erstellt haben, können wir die API-Ansichten hinzufügen.

Hinzufügen der API-Ansichten

In diesem Abschnitt erstellen wir die API-Ansichten für unsere Anwendung, die von Django aufgerufen werden, wenn der Benutzer den Endpunkt besucht, der der Ansichtsfunktion entspricht.

Öffnen Sie~/djangoreactproject/customers/views.py:

nano ~/djangoreactproject/customers/views.py

Löschen Sie, was dort ist, und fügen Sie die folgenden Importe hinzu:

~/djangoreactproject/customers/views.py

from rest_framework.response import Response
from rest_framework.decorators import api_view
from rest_framework import status

from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from .models import Customer
from .serializers import *

Wir importieren den von uns erstellten Serializer zusammen mit dem ModellCustomerund den REST Framework-APIs von Django und Django.

Fügen Sie als Nächstes die Ansicht für die Verarbeitung von POST- und GET-HTTP-Anforderungen hinzu:

~/djangoreactproject/customers/views.py

...

@api_view(['GET', 'POST'])
def customers_list(request):
    """
 List  customers, or create a new customer.
 """
    if request.method == 'GET':
        data = []
        nextPage = 1
        previousPage = 1
        customers = Customer.objects.all()
        page = request.GET.get('page', 1)
        paginator = Paginator(customers, 10)
        try:
            data = paginator.page(page)
        except PageNotAnInteger:
            data = paginator.page(1)
        except EmptyPage:
            data = paginator.page(paginator.num_pages)

        serializer = CustomerSerializer(data,context={'request': request} ,many=True)
        if data.has_next():
            nextPage = data.next_page_number()
        if data.has_previous():
            previousPage = data.previous_page_number()

        return Response({'data': serializer.data , 'count': paginator.count, 'numpages' : paginator.num_pages, 'nextlink': '/api/customers/?page=' + str(nextPage), 'prevlink': '/api/customers/?page=' + str(previousPage)})

    elif request.method == 'POST':
        serializer = CustomerSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

Zuerst verwenden wir den Dekorator@api_view(['GET', 'POST']), um eine API-Ansicht zu erstellen, die GET- und POST-Anforderungen akzeptieren kann. Adecorator ist eine Funktion, die eine andere Funktion übernimmt und dynamisch erweitert.

Im Methodenkörper verwenden wir die Variablerequest.method, um die aktuelle HTTP-Methode zu überprüfen und die entsprechende Logik abhängig vom Anforderungstyp auszuführen:

  • Wenn es sich um eine GET-Anforderung handelt, paginiert die Methode die Daten mit DjangoPaginator und gibt die erste Datenseite nach der Serialisierung, die Anzahl der verfügbaren Kunden, die Anzahl der verfügbaren Seiten und die Links zu den vorherigen und nächsten Seiten zurück . Paginator ist eine integrierte Django-Klasse, die eine Liste von Daten in Seiten paginiert und Methoden für den Zugriff auf die Elemente für jede Seite bereitstellt.

  • Wenn es sich um eine POST-Anforderung handelt, serialisiert die Methode die empfangenen Kundendaten und ruft dann diesave()-Methode des Serializer-Objekts auf. Anschließend wird ein Antwortobjekt, eine Instanz vonHttpResponse, mit dem Statuscode 201 zurückgegeben. Jede von Ihnen erstellte Ansicht ist für die Speicherung einesHttpResponse-Objekts verantwortlich. Die Methodesave() speichert die serialisierten Daten in der Datenbank.

Weitere Informationen zuHttpResponse und Ansichten finden Sie in dieser Diskussion zucreating view functions.

Fügen Sie nun die API-Ansicht hinzu, die für die Verarbeitung der GET-, PUT- und DELETE-Anforderungen zum Abrufen, Aktualisieren und Löschen von Kunden umpk (Primärschlüssel) verantwortlich ist:

~/djangoreactproject/customers/views.py

...
@api_view(['GET', 'PUT', 'DELETE'])
def customers_detail(request, pk):
 """
 Retrieve, update or delete a customer by id/pk.
 """
    try:
        customer = Customer.objects.get(pk=pk)
    except Customer.DoesNotExist:
        return Response(status=status.HTTP_404_NOT_FOUND)

    if request.method == 'GET':
        serializer = CustomerSerializer(customer,context={'request': request})
        return Response(serializer.data)

    elif request.method == 'PUT':
        serializer = CustomerSerializer(customer, data=request.data,context={'request': request})
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    elif request.method == 'DELETE':
        customer.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)

Die Methode ist mit@api_view(['GET', 'PUT', 'DELETE']) dekoriert, um anzuzeigen, dass es sich um eine API-Ansicht handelt, die GET-, PUT- und DELETE-Anforderungen akzeptieren kann.

Die Prüfung im Feldrequest.method überprüft die Anforderungsmethode und ruft abhängig von ihrem Wert die richtige Logik auf:

  • Wenn es sich um eine GET-Anforderung handelt, werden Kundendaten serialisiert und mithilfe eines Response-Objekts gesendet.

  • Wenn es sich um eine PUT-Anforderung handelt, erstellt die Methode einen Serialisierer für neue Kundendaten. Als Nächstes wird diesave()-Methode des erstellten Serializer-Objekts aufgerufen. Schließlich wird ein Response-Objekt mit dem aktualisierten Kunden gesendet.

  • Wenn es sich um eine DELETE-Anforderung handelt, ruft die Methode diedelete()-Methode des Kundenobjekts auf, um es zu löschen, und gibt dann ein Antwortobjekt ohne Daten zurück.

Die fertige Datei sieht folgendermaßen aus:

~/djangoreactproject/customers/views.py

from rest_framework.response import Response
from rest_framework.decorators import api_view
from rest_framework import status

from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from .models import Customer
from .serializers import *


@api_view(['GET', 'POST'])
def customers_list(request):
    """
 List  customers, or create a new customer.
 """
    if request.method == 'GET':
        data = []
        nextPage = 1
        previousPage = 1
        customers = Customer.objects.all()
        page = request.GET.get('page', 1)
        paginator = Paginator(customers, 5)
        try:
            data = paginator.page(page)
        except PageNotAnInteger:
            data = paginator.page(1)
        except EmptyPage:
            data = paginator.page(paginator.num_pages)

        serializer = CustomerSerializer(data,context={'request': request} ,many=True)
        if data.has_next():
            nextPage = data.next_page_number()
        if data.has_previous():
            previousPage = data.previous_page_number()

        return Response({'data': serializer.data , 'count': paginator.count, 'numpages' : paginator.num_pages, 'nextlink': '/api/customers/?page=' + str(nextPage), 'prevlink': '/api/customers/?page=' + str(previousPage)})

    elif request.method == 'POST':
        serializer = CustomerSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

@api_view(['GET', 'PUT', 'DELETE'])
def customers_detail(request, pk):
    """
 Retrieve, update or delete a customer by id/pk.
 """
    try:
        customer = Customer.objects.get(pk=pk)
    except Customer.DoesNotExist:
        return Response(status=status.HTTP_404_NOT_FOUND)

    if request.method == 'GET':
        serializer = CustomerSerializer(customer,context={'request': request})
        return Response(serializer.data)

    elif request.method == 'PUT':
        serializer = CustomerSerializer(customer, data=request.data,context={'request': request})
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    elif request.method == 'DELETE':
        customer.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)

Wir können jetzt mit dem Erstellen unserer Endpunkte fortfahren.

API-Endpunkte hinzufügen

Wir werden nun die API-Endpunkte erstellen:api/customers/ zum Abfragen und Erstellen von Kunden undapi/customers/<pk> zum Abrufen, Aktualisieren oder Löschen einzelner Kunden nachpk.

Öffnen Sie~/djangoreactproject/djangoreactproject/urls.py:

nano ~/djangoreactproject/djangoreactproject/urls.py

Lassen Sie das, was da ist, aber fügen Sie den Import zu den Ansichten voncustomersoben in der Datei hinzu:

~/djangoreactproject/djangoreactproject/urls.py

from django.contrib import admin
from django.urls import path
from customers import views
from django.conf.urls import url

Fügen Sie als Nächstes die URLsapi/customers/ undapi/customers/<pk>zu denurlpatterns list hinzu, die die URLs der Anwendung enthalten:

~/djangoreactproject/djangoreactproject/urls.py

...

urlpatterns = [
    path('admin/', admin.site.urls),
    url(r'^api/customers/$', views.customers_list),
    url(r'^api/customers/(?P[0-9]+)$', views.customers_detail),
]

Nachdem unsere REST-Endpunkte erstellt wurden, wollen wir sehen, wie wir sie nutzen können.

[[Schritt 6 - Konsumieren der restlichen API mit Axios] == Schritt 6 - Konsumieren der REST-API mit Axios

In diesem Schritt installieren wirAxios, den HTTP-Client, mit dem wir API-Aufrufe durchführen. Wir erstellen auch eine Klasse, um die von uns erstellten API-Endpunkte zu verwenden.

Deaktivieren Sie zunächst Ihre virtuelle Umgebung:

deactivate

Navigieren Sie als Nächstes zum Ordnerfrontend:

cd ~/djangoreactproject/frontend

Installieren Sieaxios vonnpm mit:

npm install axios --save

Mit der Option--save wird die Abhängigkeit vonaxioszurpackage.json-Datei Ihrer Anwendung hinzugefügt.

Erstellen Sie als Nächstes eine JavaScript-Datei mit dem NamenCustomersService.js, die den Code zum Aufrufen der REST-APIs enthält. Wir machen dies im Ordnersrc, in dem sich der Anwendungscode für unser Projekt befindet:

cd src
nano CustomersService.js

Fügen Sie den folgenden Code hinzu, der Methoden zum Herstellen einer Verbindung mit der Django-REST-API enthält:

~/djangoreactproject/frontend/src/CustomersService.js

import axios from 'axios';
const API_URL = 'http://localhost:8000';

export default class CustomersService{

    constructor(){}


    getCustomers() {
        const url = `${API_URL}/api/customers/`;
        return axios.get(url).then(response => response.data);
    }
    getCustomersByURL(link){
        const url = `${API_URL}${link}`;
        return axios.get(url).then(response => response.data);
    }
    getCustomer(pk) {
        const url = `${API_URL}/api/customers/${pk}`;
        return axios.get(url).then(response => response.data);
    }
    deleteCustomer(customer){
        const url = `${API_URL}/api/customers/${customer.pk}`;
        return axios.delete(url);
    }
    createCustomer(customer){
        const url = `${API_URL}/api/customers/`;
        return axios.post(url,customer);
    }
    updateCustomer(customer){
        const url = `${API_URL}/api/customers/${customer.pk}`;
        return axios.put(url,customer);
    }
}

Die KlasseCustomersServiceruft die folgenden Axios-Methoden auf:

  • getCustomers(): Ruft die erste Seite der Kunden ab.

  • getCustomersByURL(): Ruft Kunden per URL ab. Dies ermöglicht es, die nächsten Seiten von Kunden zu erhalten, indem Links wie/api/customers/?page=2 übergeben werden.

  • getCustomer(): Ruft einen Kunden per Primärschlüssel ab.

  • createCustomer(): Erstellt einen Kunden.

  • updateCustomer(): Aktualisiert einen Kunden.

  • deleteCustomer(): Löscht einen Kunden.

Wir können jetzt die Daten von unserer API in unserer React UI-Oberfläche anzeigen, indem wir eineCustomersList-Komponente erstellen.

[[Schritt 7 - Anzeigen von Daten aus der API in der Reaktionsanwendung] == Schritt 7 - Anzeigen von Daten aus der API in der Reaktionsanwendung

In diesem Schritt erstellen wir dieCustomersList Reactcomponent. Eine Reaktionskomponente repräsentiert einen Teil der Benutzeroberfläche. Sie können die Benutzeroberfläche auch in unabhängige, wiederverwendbare Teile aufteilen.

Beginnen Sie mit der Erstellung vonCustomersList.js infrontend/src:

nano ~/djangoreactproject/frontend/src/CustomersList.js

Importieren Sie zunächstReact undComponent, um eine React-Komponente zu erstellen:

~/djangoreactproject/frontend/src/CustomersList.js

import  React, { Component } from  'react';

Importieren und instanziieren Sie als Nächstes dasCustomersService-Modul, das Sie im vorherigen Schritt erstellt haben und das Methoden bereitstellt, die mit dem REST-API-Backend verbunden sind:

~/djangoreactproject/frontend/src/CustomersList.js

...
import  CustomersService  from  './CustomersService';

const  customersService  =  new  CustomersService();

Erstellen Sie als Nächstes eineCustomersList-Komponente, dieComponent erweitert, um die REST-API aufzurufen. Eine Reaktionskomponente sollteextend or subclass the Component class betragen. Weitere Informationen zu E6-Klassen und Vererbung finden Sie in unserem Tutorial zuUnderstanding Classes in JavaScript.

Fügen Sie den folgenden Code hinzu, um eine React-Komponente zu erstellen, diereact.Component erweitert:

~/djangoreactproject/frontend/src/CustomersList.js

...
class  CustomersList  extends  Component {

    constructor(props) {
        super(props);
        this.state  = {
            customers: [],
            nextPageURL:  ''
        };
        this.nextPage  =  this.nextPage.bind(this);
        this.handleDelete  =  this.handleDelete.bind(this);
    }
}
export  default  CustomersList;

Innerhalb derconstructor initialisieren wir dasstate-Objekt. Dies enthält die Zustandsvariablen unserer Komponente unter Verwendung eines leerencustomersarray. Dieses Array enthält Kunden undnextPageURL, die die URL der nächsten Seite enthalten, die von der Back-End-API abgerufen werden soll. Wir sind auchbinding dienextPage() undhandleDelete()methods bisthis, so dass sie über den HTML-Code zugänglich sind.

Fügen Sie als Nächstes diecomponentDidMount()-Methode und einen Aufruf vongetCustomers() innerhalb derCustomersList-Klasse vor der schließenden geschweiften Klammer hinzu.

Die MethodecomponentDidMount() ist eine Lebenszyklusmethode der Komponente, die aufgerufen wird, wenn die Komponente erstellt und in das DOM eingefügt wird. getCustomers() ruft das Customers Service-Objekt auf, um die erste Datenseite und den Link der nächsten Seite vom Django-Backend abzurufen:

~/djangoreactproject/frontend/src/CustomersList.js

...
componentDidMount() {
    var  self  =  this;
    customersService.getCustomers().then(function (result) {
        self.setState({ customers:  result.data, nextPageURL:  result.nextlink})
    });
}

Fügen Sie nun die MethodehandleDelete(), mit der ein Kunde gelöscht wird, untercomponentDidMount() hinzu:

~/djangoreactproject/frontend/src/CustomersList.js

...
handleDelete(e,pk){
    var  self  =  this;
    customersService.deleteCustomer({pk :  pk}).then(()=>{
        var  newArr  =  self.state.customers.filter(function(obj) {
            return  obj.pk  !==  pk;
        });
        self.setState({customers:  newArr})
    });
}

Die MethodehandleDelete() ruft die MethodedeleteCustomer() auf, um einen Kunden mitpk (Primärschlüssel) zu löschen. Wenn der Vorgang erfolgreich ist, wird das Arraycustomersfür den entfernten Kunden herausgefiltert.

Fügen Sie als Nächstes einenextPage()-Methode hinzu, um die Daten für die nächste Seite abzurufen und den Link für die nächste Seite zu aktualisieren:

~/djangoreactproject/frontend/src/CustomersList.js

...
nextPage(){
    var  self  =  this;
    customersService.getCustomersByURL(this.state.nextPageURL).then((result) => {
        self.setState({ customers:  result.data, nextPageURL:  result.nextlink})
    });
}

Die MethodenextPage() ruft eine MethodegetCustomersByURL() auf, die die URL der nächsten Seite aus dem Statusobjektthis.state.nextPageURL entnimmt und das Arraycustomers mit den zurückgegebenen Daten aktualisiert.

Fügen Sie abschließend die Komponenterender() method hinzu, die eine Kundentabelle aus dem Komponentenstatus rendert:

~/djangoreactproject/frontend/src/CustomersList.js

...
render() {

    return (
    
{this.state.customers.map( c => )}
# First Name Last Name Phone Email Address Description Actions
{c.pk} {c.first_name} {c.last_name} {c.phone} {c.email} {c.address} {c.description} Update
); }

Dies ist der vollständige Inhalt der Datei:

~/djangoreactproject/frontend/src/CustomersList.js

import  React, { Component } from  'react';
import  CustomersService  from  './CustomersService';

const  customersService  =  new  CustomersService();

class  CustomersList  extends  Component {

constructor(props) {
    super(props);
    this.state  = {
        customers: [],
        nextPageURL:  ''
    };
    this.nextPage  =  this.nextPage.bind(this);
    this.handleDelete  =  this.handleDelete.bind(this);
}

componentDidMount() {
    var  self  =  this;
    customersService.getCustomers().then(function (result) {
        console.log(result);
        self.setState({ customers:  result.data, nextPageURL:  result.nextlink})
    });
}
handleDelete(e,pk){
    var  self  =  this;
    customersService.deleteCustomer({pk :  pk}).then(()=>{
        var  newArr  =  self.state.customers.filter(function(obj) {
            return  obj.pk  !==  pk;
        });

        self.setState({customers:  newArr})
    });
}

nextPage(){
    var  self  =  this;
    console.log(this.state.nextPageURL);
    customersService.getCustomersByURL(this.state.nextPageURL).then((result) => {
        self.setState({ customers:  result.data, nextPageURL:  result.nextlink})
    });
}
render() {

    return (
        
{this.state.customers.map( c => )}
# First Name Last Name Phone Email Address Description Actions
{c.pk} {c.first_name} {c.last_name} {c.phone} {c.email} {c.address} {c.description} Update
); } } export default CustomersList;

Nachdem wir dieCustomersList-Komponente zum Anzeigen der Kundenliste erstellt haben, können wir die Komponente hinzufügen, die die Kundenerstellung und -aktualisierungen übernimmt.

[[Schritt 8 - Hinzufügen der Kundenkomponente zum Erstellen und Aktualisieren von Reaktionen]] == Schritt 8 - Hinzufügen der Komponente zum Erstellen und Aktualisieren von Kundenreaktionen

In diesem Schritt erstellen wir dieCustomerCreateUpdate-Komponente, die das Erstellen und Aktualisieren von Kunden übernimmt. Hierzu wird ein Formular bereitgestellt, mit dem Benutzer entweder Daten zu einem neuen Kunden eingeben oder einen vorhandenen Eintrag aktualisieren können.

Erstellen Sie infrontend/src eineCustomerCreateUpdate.js-Datei:

nano ~/djangoreactproject/frontend/src/CustomerCreateUpdate.js

Fügen Sie den folgenden Code hinzu, um eine React-Komponente zu erstellen undReact undComponent zu importieren:

~/djangoreactproject/frontend/src/CustomerCreateUpdate.js

import  React, { Component } from  'react';

Wir können auch dieCustomersService-Klasse importieren und instanziieren, die wir im vorherigen Schritt erstellt haben und die Methoden bereitstellt, die mit dem REST-API-Backend verbunden sind:

~/djangoreactproject/frontend/src/CustomerCreateUpdate.js

...
import  CustomersService  from  './CustomersService';

const  customersService  =  new  CustomersService();

Erstellen Sie als Nächstes eineCustomerCreateUpdate-Komponente, dieComponent erweitert, um Kunden zu erstellen und zu aktualisieren:

~/djangoreactproject/frontend/src/CustomerCreateUpdate.js

...
class  CustomerCreateUpdate  extends  Component {

    constructor(props) {
        super(props);
    }

}
export default CustomerCreateUpdate;

Fügen Sie innerhalb der Klassendefinition dierender()-Methode der Komponente hinzu, die ein HTML-Formular rendert, das Informationen über den Kunden enthält:

~/djangoreactproject/frontend/src/CustomerCreateUpdate.js

...
render() {
        return (
          
); }

Für jedes Formulareingabeelement fügt die Methode eineref-Eigenschaft hinzu, um auf den Wert des Formularelements zuzugreifen und diesen festzulegen.

Definieren Sie als Nächstes über derrender()-Methode einehandleSubmit(event)-Methode, damit Sie die richtige Funktionalität haben, wenn ein Benutzer auf die Schaltfläche "Senden" klickt:

~/djangoreactproject/frontend/src/CustomerCreateUpdate.js

...
handleSubmit(event) {
    const { match: { params } } =  this.props;
    if(params  &&  params.pk){
        this.handleUpdate(params.pk);
    }
    else
    {
        this.handleCreate();
    }
    event.preventDefault();
}

...

Die MethodehandleSubmit(event) übernimmt die Formularübermittlung und ruft je nach Route entweder die MethodehandleUpdate(pk)auf, um den Kunden mit den übergebenenpkzu aktualisieren, oder die MethodehandleCreate(), die erstellt werden soll ein neuer Kunde. Wir werden diese Methoden in Kürze definieren.

Binden Sie auf dem Komponentenkonstruktor die neu hinzugefügtehandleSubmit()-Methode anthis, damit Sie in Ihrem Formular darauf zugreifen können:

~/djangoreactproject/frontend/src/CustomerCreateUpdate.js

...
class CustomerCreateUpdate extends Component {

constructor(props) {
    super(props);
    this.handleSubmit = this.handleSubmit.bind(this);
}
...

Definieren Sie als Nächstes die MethodehandleCreate(), um einen Kunden aus den Formulardaten zu erstellen. Fügen Sie über derhandleSubmit(event)-Methode den folgenden Code hinzu:

~/djangoreactproject/frontend/src/CustomerCreateUpdate.js

...
handleCreate(){
    customersService.createCustomer(
        {
        "first_name":  this.refs.firstName.value,
        "last_name":  this.refs.lastName.value,
        "email":  this.refs.email.value,
        "phone":  this.refs.phone.value,
        "address":  this.refs.address.value,
        "description":  this.refs.description.value
        }).then((result)=>{
                alert("Customer created!");
        }).catch(()=>{
                alert('There was an error! Please re-check your form.');
        });
}

...

DiehandleCreate()-Methode wird verwendet, um einen Kunden aus eingegebenen Daten zu erstellen. Es ruft die entsprechendeCustomersService.createCustomer()-Methode auf, mit der der eigentliche API-Aufruf an das Backend erfolgt, um einen Kunden zu erstellen.

Definieren Sie als Nächstes unter der MethodehandleCreate() die MethodehandleUpdate(pk), um Aktualisierungen zu implementieren:

~/djangoreactproject/frontend/src/CustomerCreateUpdate.js

...
handleUpdate(pk){
customersService.updateCustomer(
    {
    "pk":  pk,
    "first_name":  this.refs.firstName.value,
    "last_name":  this.refs.lastName.value,
    "email":  this.refs.email.value,
    "phone":  this.refs.phone.value,
    "address":  this.refs.address.value,
    "description":  this.refs.description.value
    }
    ).then((result)=>{

        alert("Customer updated!");
    }).catch(()=>{
        alert('There was an error! Please re-check your form.');
    });
}

Die MethodeupdateCustomer() aktualisiert einen Kunden umpk unter Verwendung der neuen Informationen aus dem Kundeninformationsformular. Es ruft die MethodecustomersService.updateCustomer()auf.

Fügen Sie als Nächstes einecomponentDidMount()-Methode hinzu. Wenn der Benutzer die Route einescustomer/:pkbesucht, möchten wir das Formular mit Informationen zum Kunden füllen, indem wir den Primärschlüssel aus der URL verwenden. Dazu können wir die MethodegetCustomer(pk) hinzufügen, nachdem die Komponente im Lebenszyklusereignis voncomponentDidMount() bereitgestellt wurde. Fügen Sie den folgenden Code unterhalb des Komponentenkonstruktors hinzu, um diese Methode hinzuzufügen:

~/djangoreactproject/frontend/src/CustomerCreateUpdate.js

...
componentDidMount(){
    const { match: { params } } =  this.props;
    if(params  &&  params.pk)
    {
        customersService.getCustomer(params.pk).then((c)=>{
            this.refs.firstName.value  =  c.first_name;
            this.refs.lastName.value  =  c.last_name;
            this.refs.email.value  =  c.email;
            this.refs.phone.value  =  c.phone;
            this.refs.address.value  =  c.address;
            this.refs.description.value  =  c.description;
        })
    }
}

Dies ist der vollständige Inhalt der Datei:

~/djangoreactproject/frontend/src/CustomerCreateUpdate.js

import React, { Component } from 'react';
import CustomersService from './CustomersService';

const customersService = new CustomersService();

class CustomerCreateUpdate extends Component {
    constructor(props) {
        super(props);

        this.handleSubmit = this.handleSubmit.bind(this);
      }

      componentDidMount(){
        const { match: { params } } = this.props;
        if(params && params.pk)
        {
          customersService.getCustomer(params.pk).then((c)=>{
            this.refs.firstName.value = c.first_name;
            this.refs.lastName.value = c.last_name;
            this.refs.email.value = c.email;
            this.refs.phone.value = c.phone;
            this.refs.address.value = c.address;
            this.refs.description.value = c.description;
          })
        }
      }

      handleCreate(){
        customersService.createCustomer(
          {
            "first_name": this.refs.firstName.value,
            "last_name": this.refs.lastName.value,
            "email": this.refs.email.value,
            "phone": this.refs.phone.value,
            "address": this.refs.address.value,
            "description": this.refs.description.value
        }
        ).then((result)=>{
          alert("Customer created!");
        }).catch(()=>{
          alert('There was an error! Please re-check your form.');
        });
      }
      handleUpdate(pk){
        customersService.updateCustomer(
          {
            "pk": pk,
            "first_name": this.refs.firstName.value,
            "last_name": this.refs.lastName.value,
            "email": this.refs.email.value,
            "phone": this.refs.phone.value,
            "address": this.refs.address.value,
            "description": this.refs.description.value
        }
        ).then((result)=>{
          console.log(result);
          alert("Customer updated!");
        }).catch(()=>{
          alert('There was an error! Please re-check your form.');
        });
      }
      handleSubmit(event) {
        const { match: { params } } = this.props;

        if(params && params.pk){
          this.handleUpdate(params.pk);
        }
        else
        {
          this.handleCreate();
        }

        event.preventDefault();
      }

      render() {
        return (
          
); } } export default CustomerCreateUpdate;

Wenn die KomponenteCustomerCreateUpdateerstellt wurde, können wir die HauptkomponenteAppaktualisieren, um Links zu den verschiedenen von uns erstellten Komponenten hinzuzufügen.

[[Schritt 9 - Aktualisieren der Haupt-App-Komponente]] == Schritt 9 - Aktualisieren der Haupt-App-Komponente

In diesem Abschnitt aktualisieren wir dieApp-Komponente unserer Anwendung, um Links zu den Komponenten zu erstellen, die wir in den vorherigen Schritten erstellt haben.

Führen Sie im Ordnerfrontend den folgenden Befehl aus, umReact Router zu installieren, mit dem Sie Routing und Navigation zwischen verschiedenen React-Komponenten hinzufügen können:

cd ~/djangoreactproject/frontend
npm install --save react-router-dom

Öffnen Sie als nächstes~/djangoreactproject/frontend/src/App.js:

nano ~/djangoreactproject/frontend/src/App.js

Löschen Sie alles, was sich dort befindet, und fügen Sie den folgenden Code hinzu, um die erforderlichen Klassen zum Hinzufügen von Routing zu importieren. Dazu gehörenBrowserRouter, mit dem eine Routerkomponente erstellt wird, undRoute, mit dem eine Routenkomponente erstellt wird:

~/djangoreactproject/frontend/src/App.js

import  React, { Component } from  'react';
import { BrowserRouter } from  'react-router-dom'
import { Route, Link } from  'react-router-dom'
import  CustomersList  from  './CustomersList'
import  CustomerCreateUpdate  from  './CustomerCreateUpdate'
import  './App.css';

BrowserRouter hält die Benutzeroberfläche mithilfe vonHTML5 history API mit der URL synchron.

Erstellen Sie als Nächstes ein Basislayout, das die Basiskomponente bereitstellt, die von derBrowserRouter-Komponente umbrochen werden soll:

~/djangoreactproject/frontend/src/App.js

...

const  BaseLayout  = () => (

)

Wir verwenden die KomponenteRoute, um die Routen unserer Anwendung zu definieren. Die Komponente, die der Router laden soll, sobald eine Übereinstimmung gefunden wurde. Jede Route benötigtpath, um den zuzuordnenden Pfad anzugeben, undcomponent, um die zu ladende Komponente anzugeben. Die Eigenschaftexact weist den Router an, dem genauen Pfad zu entsprechen.

Erstellen Sie abschließend dieApp-Komponente, die Root- oder Top-Level-Komponente unserer React-Anwendung:

~/djangoreactproject/frontend/src/App.js

...

class  App  extends  Component {

render() {
    return (
    
        
    
    );
}
}
export  default  App;

Wir haben dieBaseLayout-Komponente mit derBrowserRouter-Komponente umbrochen, da unsere App im Browser ausgeführt werden soll.

Die fertige Datei sieht folgendermaßen aus:

~/djangoreactproject/frontend/src/App.js

import React, { Component } from 'react';
import { BrowserRouter } from 'react-router-dom'
import { Route, Link } from 'react-router-dom'

import  CustomersList from './CustomersList'
import  CustomerCreateUpdate  from './CustomerCreateUpdate'
import './App.css';

const BaseLayout = () => (
  
)

class App extends Component {
  render() {
    return (
      
        
      
    );
  }
}

export default App;

Nachdem Sie der Anwendung das Routing hinzugefügt haben, können Sie die Anwendung jetzt testen. Navigieren Sie zuhttp://localhost:3000. Sie sollten die erste Seite der Anwendung sehen:

Application Home Page

Mit dieser Anwendung haben Sie jetzt die Basis für eine CRM-Anwendung.

Fazit

In diesem Tutorial haben Sie eine Demo-Anwendung mit Django und React erstellt. Sie haben das Django-REST-Framework verwendet, um die REST-API zu erstellen, Axios, um die API zu verwenden, und Bootstrap 4, um Ihr CSS zu gestalten. Den Quellcode dieses Projekts finden Sie inGitHub repository.

In diesem Tutorial-Setup wurden separate Front-End- und Back-End-Apps verwendet. Überprüfen Sie für einen anderen Ansatz zur Integration von React in Django diesetutorial und diesetutorial.

Weitere Informationen zum Erstellen einer Anwendung mit Django finden Sie inDjango development series. Sie können sich auch dieofficial Django docs ansehen.