Djangoで顧客情報を管理し、Ubuntu18.04でReactするための最新のWebアプリケーションを構築する方法
序章
人々はさまざまな種類のデバイスを使用してインターネットに接続し、Webを閲覧します。 このため、アプリケーションはさまざまな場所からアクセスできる必要があります。 従来のWebサイトの場合、通常は応答性の高いUIで十分ですが、より複雑なアプリケーションでは、他の手法やアーキテクチャを使用する必要があります。 これには、クライアント側のWebアプリケーション、プログレッシブWebアプリ(PWA)、またはネイティブモバイルアプリとして実装できる個別のRESTバックエンドアプリケーションとフロントエンドアプリケーションが含まれます。
より複雑なアプリケーションを構築するときに使用できるツールには、次のものがあります。
- React 、開発者がRESTAPIバックエンド用のWebおよびネイティブフロントエンドを構築できるようにするJavaScriptフレームワーク。
- Django は、 model view controller(MVC)ソフトウェアアーキテクチャパターンに従った、無料のオープンソースPythonWebフレームワークです。
- Django RESTフレームワーク、DjangoでRESTAPIを構築するための強力で柔軟なツールキット。
このチュートリアルでは、React、Django、およびDjango RESTフレームワークを使用して、個別のRESTAPIバックエンドとフロントエンドを備えた最新のWebアプリケーションを構築します。 React with Djangoを使用することで、JavaScriptとフロントエンド開発の最新の進歩から利益を得ることができます。 組み込みのテンプレートエンジンを使用するDjangoアプリケーションを構築する代わりに、ReactをUIライブラリとして使用し、仮想ドキュメントオブジェクトモデル(DOM)、宣言型アプローチ、およびデータの変更をすばやくレンダリングするコンポーネントを利用します。
作成するWebアプリケーションは、顧客に関するレコードをデータベースに保存し、CRMアプリケーションの開始点として使用できます。 終了すると、 Bootstrap 4 でスタイル設定されたReactインターフェースを使用して、レコードを作成、読み取り、更新、および削除できるようになります。
前提条件
このチュートリアルを完了するには、次のものが必要です。
- Ubuntu18.04を搭載した開発マシン。
- Python 3、
pip
、 とvenv
Python3をインストールしてUbuntu18.04にローカルプログラミング環境をセットアップする方法のステップ1と2に従ってマシンにインストールします。 - Node.js6+および
npm
マシンに5.2以降がインストールされている。 PPAからインストールする場合は、 Ubuntu18.04にNode.jsをインストールする方法の手順に従って両方をインストールできます。
ステップ1—Python仮想環境の作成と依存関係のインストール
このステップでは、仮想環境を作成し、Django、Django RESTフレームワーク、およびDjangoRESTフレームワークを含むアプリケーションに必要な依存関係をインストールします。 django-cors-headers
.
このアプリケーションでは、DjangoとReactに2つの異なる開発サーバーを使用します。 これらは異なるポートで実行され、2つの別個のドメインとして機能します。 このため、クロスオリジンリソースシェアリング(CORS)を有効にして、ブラウザーによってブロックされることなくReactからDjangoにHTTPリクエストを送信する必要があります。
ホームディレクトリに移動し、を使用して仮想環境を作成します venv
Python 3モジュール:
- cd ~
- python3 -m venv ./env
を使用して、作成した仮想環境をアクティブ化します source
:
- source env/bin/activate
次に、プロジェクトの依存関係をでインストールします pip
. これらには以下が含まれます:
- Django :プロジェクトのWebフレームワーク。
- Django RESTフレームワーク:Djangoを使用してRESTAPIを構築するサードパーティアプリケーション。
- django-cors-headers :CORSを有効にするパッケージ。
Djangoフレームワークをインストールします。
- pip install django djangorestframework django-cors-headers
プロジェクトの依存関係をインストールすると、DjangoプロジェクトとReactフロントエンドを作成できます。
ステップ2—Djangoプロジェクトを作成する
このステップでは、次のコマンドとユーティリティを使用してDjangoプロジェクトを生成します。
-
django-admin startproject project-name : django-admin は、Djangoでタスクを実行するために使用されるコマンドラインユーティリティです。 The
startproject
コマンドは新しいDjangoプロジェクトを作成します。 -
python manage.py startapp myapp :
manage.py
は、各Djangoプロジェクトに自動的に追加されるユーティリティスクリプトであり、新しいアプリケーションの作成、データベースの移行、Djangoプロジェクトのローカルでの提供などの多くの管理タスクを実行します。 これはstartapp
コマンドは、Djangoプロジェクト内にDjangoアプリケーションを作成します。 Djangoでは、 application という用語は、プロジェクトにいくつかの機能セットを提供するPythonパッケージを表します。
まず、でDjangoプロジェクトを作成します django-admin startproject
. 私たちのプロジェクトを呼びます djangoreactproject
:
- django-admin startproject djangoreactproject
先に進む前に、Djangoプロジェクトのディレクトリ構造を見てみましょう。 tree
指図。
ヒント: tree
コマンドラインからファイルとディレクトリの構造を表示するための便利なコマンドです。 次のコマンドでインストールできます。
- sudo apt-get install tree
使用するには、 cd
必要なディレクトリに入力して入力します tree
または、開始点へのパスを tree /home/sammy/sammys-project
.
に移動します djangoreactproject
プロジェクトルート内のフォルダを実行し、 tree
指図:
- cd ~/djangoreactproject
- tree
次の出力が表示されます。
Output├── djangoreactproject
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
└── manage.py
The ~/djangoreactproject
フォルダはプロジェクトのルートです。 このフォルダ内には、作業に重要ないくつかのファイルがあります。
- manage.py :いくつかの管理タスクを実行するユーティリティスクリプト。
- settings.py :プロジェクトの設定を変更できるDjangoプロジェクトのメイン構成ファイル。 これらの設定には、次のような変数が含まれます
INSTALLED_APPS
、プロジェクトで有効なアプリケーションを指定する文字列のリスト。 Djangoのドキュメントには、使用可能な設定に関する詳細情報があります。 - urls.py :このファイルには、URLパターンと関連するビューのリストが含まれています。 各パターンは、URLとそのURLに対して呼び出される関数との間の接続をマップします。 URLとビューの詳細については、Djangoビューの作成方法のチュートリアルを参照してください。
プロジェクトでの作業の最初のステップは、前のステップでインストールしたパッケージ(DjangoRESTフレームワークやDjangoCORSパッケージなど)をに追加して構成することです。 settings.py
. でファイルを開く nano
またはお気に入りの編集者:
- nano ~/djangoreactproject/djangoreactproject/settings.py
に移動します INSTALLED_APPS
設定して追加します rest_framework
と corsheaders
リストの一番下にあるアプリケーション:
...
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'corsheaders'
]
次に、 corsheaders.middleware.CorsMiddleware
以前にインストールされたCORSパッケージから MIDDLEWARE
設定。 この設定は、ミドルウェアのリストです。これは、Webアプリケーションが要求または応答を処理するたびに処理されるコードを含むPythonクラスです。
...
MIDDLEWARE = [
...
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'corsheaders.middleware.CorsMiddleware'
]
次に、CORSを有効にできます。 The CORS_ORIGIN_ALLOW_ALL
設定は、すべてのドメインにCORSを許可するかどうかを指定します。 CORS_ORIGIN_WHITELIST
許可されたURLを含むPythonタプルです。 私たちの場合、React開発サーバーはで実行されるため http://localhost:3000
、新しいものを追加します CORS_ORIGIN_ALLOW_ALL = False
と CORS_ORIGIN_WHITELIST('localhost:3000',)
私たちの設定 settings.py
ファイル。 次の設定をファイルの任意の場所に追加します。
...
CORS_ORIGIN_ALLOW_ALL = False
CORS_ORIGIN_WHITELIST = (
'localhost:3000',
)
...
その他の構成オプションは、 django-cors-headersdocsにあります。
ファイルを保存し、終了したらエディターを終了します。
まだ ~/djangoreactproject
ディレクトリ、という新しいDjangoアプリケーションを作成します customers
:
- python manage.py startapp customers
これには、顧客を管理するためのモデルおよびビューが含まれます。 モデルはアプリケーションデータのフィールドと動作を定義し、ビューはアプリケーションがWebリクエストを適切に処理し、必要な応答を返すことを可能にします。
次に、このアプリケーションをプロジェクトのインストール済みアプリケーションのリストに追加します settings.py
Djangoがそれをプロジェクトの一部として認識するようにファイルします。 開ける settings.py
また:
- nano ~/djangoreactproject/djangoreactproject/settings.py
追加します customers
応用:
...
INSTALLED_APPS = [
...
'rest_framework',
'corsheaders',
'customers'
]
...
次に、データベースを移行して、ローカル開発サーバーを起動します。 Migrations は、モデルに加えた変更をデータベーススキーマに伝達するDjangoの方法です。 これらの変更には、たとえば、フィールドの追加やモデルの削除などが含まれます。 モデルと移行の詳細については、Djangoモデルの作成方法を参照してください。
データベースを移行します。
- python manage.py migrate
ローカル開発サーバーを起動します。
- python manage.py runserver
次のような出力が表示されます。
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.
Webアプリケーションはから実行されます http://127.0.0.1:8000
. Webブラウザでこのアドレスに移動すると、次のページが表示されます。
この時点で、アプリケーションを実行したままにし、新しいターミナルを開いてプロジェクトの開発を続行します。
ステップ3—Reactフロントエンドを作成する
このセクションでは、Reactを使用してプロジェクトのフロントエンドアプリケーションを作成します。
Reactには、Webpackを直接構成しなくてもReactプロジェクトをすばやく生成できる公式ユーティリティがあります。 Webpackは、JavaScriptコード、CSS、画像などのWebアセットをバンドルするために使用されるモジュールバンドラーです。 通常、Webpackを使用する前に、さまざまな構成オプションを設定する必要がありますが、 create-react-app
より詳細な制御が必要であると判断するまで、Webpackを直接処理する必要がないユーティリティ。 走る create-react-app
実行するツールであるnpxを使用できます npm
パッケージバイナリ。
2番目のターミナルで、プロジェクトディレクトリにいることを確認します。
- cd ~/djangoreactproject
と呼ばれるReactプロジェクトを作成します frontend
を使用して create-react-app
と npx
:
- npx create-react-app frontend
次に、Reactアプリケーション内をナビゲートし、開発サーバーを起動します。
- cd ~/djangoreactproject/frontend
- npm start
アプリケーションはから実行されます http://localhost:3000/
:
React開発サーバーを実行したままにし、別のターミナルウィンドウを開いて続行します。
この時点でプロジェクト全体のディレクトリ構造を確認するには、ルートフォルダに移動して実行します tree
また:
- cd ~/djangoreactproject
- tree
次のような構造が表示されます。
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
このアプリケーションは、Bootstrap 4を使用してReactインターフェースのスタイルを設定するため、これをに含めます。 frontend/src/App.css
CSS設定を管理するファイル。 ファイルを開きます。
- nano ~/djangoreactproject/frontend/src/App.css
次のimportをファイルの先頭に追加します。 ファイルの既存のコンテンツを削除できますが、必須ではありません。
@import 'https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css';
ここ、 @import
他のスタイルシートからスタイルルールをインポートするために使用されるCSS命令です。
バックエンドアプリケーションとフロントエンドアプリケーションの両方を作成したので、Customerモデルといくつかのデモデータを作成しましょう。
ステップ4—顧客モデルと初期データの作成
DjangoアプリケーションとReactフロントエンドを作成したら、次のステップは、顧客に関する情報を保持するデータベーステーブルを表すCustomerモデルを作成することです。 Django Object Relational Mapper(ORM)は、Pythonクラスと変数をSQLテーブルと列にマッピングすることでデータベース操作を処理するため、SQLは必要ありません。 このようにして、Django ORMは、Pythonインターフェースを介してデータベースとのSQLの相互作用を抽象化します。
仮想環境を再度アクティブ化します。
- cd ~
- source env/bin/activate
に移動します customers
ディレクトリを開き、 models.py
、アプリケーションのモデルを保持するPythonファイル:
- cd ~/djangoreactproject/customers/
- nano models.py
このファイルには、次の内容が含まれます。
from django.db import models
# Create your models here.
CustomerモデルのAPIは、 from django.db import models
インポートステートメント。 ここで、 Customer
クラス、拡張 models.Model
. Djangoの各モデルは、django.db.models.Modelを拡張するPythonクラスです。
The Customer
モデルには次のデータベースフィールドがあります。
- first_name —顧客の名。
- last_name —顧客の姓。
- email —顧客の電子メールアドレス。
- phone —顧客の電話番号。
- address —顧客の住所。
- description —顧客の説明。
- createdAt —顧客が追加された日付。
また、 __str__()
モデルの表示方法を定義する関数。 私たちの場合、それは顧客の名になります。 クラスの構築とオブジェクトの定義の詳細については、 Python3でクラスを構築してオブジェクトを定義する方法を参照してください。
次のコードをファイルに追加します。
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
次に、データベースを移行してデータベーステーブルを作成します。 makemigrations コマンドは、モデルの変更が追加される移行ファイルを作成し、 migrate
移行ファイルの変更をデータベースに適用します。
プロジェクトのルートフォルダに戻ります。
- cd ~/djangoreactproject
以下を実行して、移行ファイルを作成します。
- python manage.py makemigrations
次のような出力が得られます。
Outputcustomers/migrations/0001_initial.py
- Create model Customer
これらの変更をデータベースに適用します。
- python manage.py migrate
移行が成功したことを示す出力が表示されます。
OutputOperations to perform:
Apply all migrations: admin, auth, contenttypes, customers, sessions
Running migrations:
Applying customers.0001_initial... OK
次に、データ移行ファイルを使用して初期顧客データを作成します。 データ移行ファイルは、データベース内のデータを追加または変更する移行です。 の空のデータ移行ファイルを作成します customers
応用:
- python manage.py makemigrations --empty --name customers customers
移行ファイルの名前とともに、次の確認が表示されます。
OutputMigrations for 'customers':
customers/migrations/0002_customers.py
移行ファイルの名前は次のとおりです。 0002_customers.py
.
次に、の移行フォルダ内を移動します customers
応用:
- cd ~/djangoreactproject/customers/migrations
作成した移行ファイルを開きます。
- nano 0002_customers.py
これはファイルの最初の内容です:
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('customers', '0001_initial'),
]
operations = [
]
importステートメントは migrations
API、移行を作成するためのDjango API、 django.db
、データベースを操作するためのクラスを含む組み込みパッケージ。
The Migration
classは、データベースの移行時に実行される操作を記述するPythonクラスです。 このクラスは拡張します migrations.Migration
そして2つのリストがあります:
- 依存関係:依存する移行が含まれます。
- operations :移行を適用するときに実行される操作が含まれます。
次に、 method を追加して、デモの顧客データを作成します。 の定義の前に次のメソッドを追加します Migration
クラス:
...
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()
...
この方法では、 Customer
私たちのクラス customers
アプリとデータベースに挿入するデモ顧客を作成します。
取得するには Customer
新しい顧客の創造を可能にするクラス、私たちは使用します get_model()
の方法 apps
物体。 The apps
オブジェクトは、インストールされているアプリケーションとそのデータベースモデルのレジストリを表します。
The apps
オブジェクトはから渡されます RunPython()
実行するために使用するときのメソッド create_data()
. 追加します migrations.RunPython()
空への方法 operations
リスト:
...
operations = [
migrations.RunPython(create_data),
]
RunPython()
は、移行でカスタムPythonコードを実行できるようにするMigrationsAPIの一部です。 私たちの operations
listは、移行を適用するときにこのメソッドが実行されることを指定します。
これは完全なファイルです:
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),
]
データ移行の詳細については、Djangoでのデータ移行に関するドキュメントを参照してください。
データベースを移行するには、最初にプロジェクトのルートフォルダーに戻ります。
- cd ~/djangoreactproject
データベースを移行して、デモデータを作成します。
- python manage.py migrate
移行を確認する出力が表示されます。
OutputOperations to perform:
Apply all migrations: admin, auth, contenttypes, customers, sessions
Running migrations:
Applying customers.0002_customers... OK
このプロセスの詳細については、Djangoモデルの作成方法を参照してください。
顧客モデルとデモデータを作成したら、RESTAPIの構築に進むことができます。
ステップ5—RESTAPIを作成する
このステップでは、DjangoRESTフレームワークを使用してRESTAPIを作成します。 いくつかの異なるAPIビューを作成します。 APIビューはAPIリクエストまたは呼び出しを処理する関数であり、APIエンドポイントはRESTシステムとのタッチポイントを表す一意のURLです。 たとえば、ユーザーがGETリクエストをAPIエンドポイントに送信すると、Djangoは対応する関数またはAPIビューを呼び出してリクエストを処理し、可能な結果を返します。
シリアライザーも利用します。 Django RESTフレームワークのシリアライザーを使用すると、複雑なモデルインスタンスとQuerySetをAPIで使用するためにJSON形式に変換できます。 シリアライザークラスは他の方向にも機能し、データを解析してDjangoモデルとQuerySetに逆シリアル化するメカニズムを提供します。
APIエンドポイントには次のものが含まれます。
api/customers
:このエンドポイントは、顧客を作成し、ページ化された顧客のセットを返すために使用されます。api/customers/<pk>
:このエンドポイントは、主キーまたはIDによって単一の顧客を取得、更新、および削除するために使用されます。
プロジェクトのURLも作成します urls.py
対応するエンドポイントのファイル(つまり api/customers
と api/customers/<pk>
).
まず、シリアライザークラスを作成します。 Customer
モデル。
シリアライザークラスの追加
のシリアライザークラスの作成 Customer
モデルは、顧客インスタンスとQuerySetをJSONとの間で変換するために必要です。 シリアライザークラスを作成するには、最初に serializers.py
内部のファイル customers
応用:
- cd ~/djangoreactproject/customers/
- nano serializers.py
次のコードを追加して、シリアライザーAPIをインポートします。 Customer
モデル:
from rest_framework import serializers
from .models import Customer
次に、拡張するシリアライザークラスを作成します serializers.ModelSerializer
シリアル化されるフィールドを指定します。
...
class CustomerSerializer(serializers.ModelSerializer):
class Meta:
model = Customer
fields = ('pk','first_name', 'last_name', 'email', 'phone','address','description')
The Meta
classは、シリアル化するモデルとフィールドを指定します。 pk
,first_name
, last_name
, email
, phone
, address
,description
.
これはファイルの完全な内容です:
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')
シリアライザークラスを作成したので、APIビューを追加できます。
APIビューの追加
このセクションでは、ユーザーがビュー関数に対応するエンドポイントにアクセスしたときにDjangoによって呼び出されるアプリケーションのAPIビューを作成します。
開ける ~/djangoreactproject/customers/views.py
:
- nano ~/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 *
作成したシリアライザーを、 Customer
モデルとDjangoおよびDjangoRESTフレームワークAPI。
次に、POSTおよびGETHTTPリクエストを処理するためのビューを追加します。
...
@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)
まず、 @api_view(['GET', 'POST'])
GETおよびPOSTリクエストを受け入れることができるAPIビューを作成するためのデコレータ。 デコレータは、別の関数を受け取り、それを動的に拡張する関数です。
メソッド本体では、 request.method
現在のHTTPメソッドをチェックし、リクエストタイプに応じて対応するロジックを実行する変数:
- GETリクエストの場合、メソッドはDjango Paginator を使用してデータをページ分割し、シリアル化後のデータの最初のページ、利用可能な顧客の数、利用可能なページの数、および前のページへのリンクを返します。次のページ。 Paginatorは、データのリストをページにページ分けし、各ページのアイテムにアクセスするためのメソッドを提供する組み込みのDjangoクラスです。
- POSTリクエストの場合、メソッドは受信した顧客データをシリアル化してから、
save()
シリアライザーオブジェクトのメソッド。 次に、201ステータスコードを持つHttpResponseのインスタンスであるResponseオブジェクトを返します。 作成する各ビューは、HttpResponse
物体。 Thesave()
メソッドは、シリアル化されたデータをデータベースに保存します。
詳細については HttpResponse
およびビューについては、ビュー関数の作成に関するこの説明を参照してください。
次に、顧客を取得、更新、および削除するためのGET、PUT、およびDELETE要求の処理を担当するAPIビューを追加します。 pk
(主キー):
...
@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)
メソッドはで飾られています @api_view(['GET', 'PUT', 'DELETE'])
GET、PUT、およびDELETEリクエストを受け入れることができるAPIビューであることを示します。
チェックイン request.method
フィールドはリクエストメソッドを検証し、その値に応じて適切なロジックを呼び出します。
- GETリクエストの場合、顧客データはシリアル化され、Responseオブジェクトを使用して送信されます。
- PUTリクエストの場合、このメソッドは新しい顧客データのシリアライザーを作成します。 次に、それは
save()
作成されたシリアライザーオブジェクトのメソッド。 最後に、更新された顧客とともにResponseオブジェクトを送信します。 - DELETEリクエストの場合、メソッドは
delete()
顧客オブジェクトのメソッドで削除し、データのないResponseオブジェクトを返します。
完成したファイルは次のようになります。
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)
これで、エンドポイントの作成に進むことができます。
APIエンドポイントの追加
ここで、APIエンドポイントを作成します。 api/customers/
、顧客のクエリと作成、および api/customers/<pk>
、単一の顧客を取得、更新、または削除するため pk
.
開ける ~/djangoreactproject/djangoreactproject/urls.py
:
- nano ~/djangoreactproject/djangoreactproject/urls.py
そこにあるものを残しますが、インポートをに追加します customers
ファイルの上部にあるビュー:
from django.contrib import admin
from django.urls import path
from customers import views
from django.conf.urls import url
次に、 api/customers/
と api/customers/<pk>
アプリケーションのURLを含むurlpatternsリストへのURL:
...
urlpatterns = [
path('admin/', admin.site.urls),
url(r'^api/customers/$', views.customers_list),
url(r'^api/customers/(?P<pk>[0-9]+)$', views.customers_detail),
]
RESTエンドポイントを作成したら、それらをどのように使用できるかを見てみましょう。
ステップ6—AxiosでRESTAPIを使用する
このステップでは、API呼び出しを行うために使用するHTTPクライアントであるAxiosをインストールします。 また、作成したAPIエンドポイントを使用するクラスも作成します。
まず、仮想環境を非アクティブ化します。
- deactivate
次に、 frontend
フォルダ:
- cd ~/djangoreactproject/frontend
インストール axios
から npm
使用:
- npm install axios --save
The --save
オプションは追加します axios
アプリケーションへの依存 package.json
ファイル。
次に、というJavaScriptファイルを作成します CustomersService.js
、RESTAPIを呼び出すためのコードが含まれます。 これを内部で作成します src
プロジェクトのアプリケーションコードが存在するフォルダ:
- cd src
- nano CustomersService.js
次のコードを追加します。このコードには、DjangoRESTAPIに接続するためのメソッドが含まれています。
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);
}
}
The CustomersService
クラスは次のAxiosメソッドを呼び出します。
getCustomers()
:顧客の最初のページを取得します。getCustomersByURL()
:URLで顧客を取得します。 これにより、次のようなリンクを渡すことで、顧客の次のページを取得できます。/api/customers/?page=2
.getCustomer()
:主キーで顧客を取得します。createCustomer()
:顧客を作成します。updateCustomer()
:顧客を更新します。deleteCustomer()
:顧客を削除します。
これで、APIからのデータをReactUIインターフェースに表示できます。 CustomersList
成分。
ステップ7—ReactアプリケーションでAPIからのデータを表示する
このステップでは、 CustomersList
コンポーネントを反応させます。 ReactコンポーネントはUIの一部を表します。 また、UIを独立した再利用可能な部分に分割することもできます。
作成することから始めます CustomersList.js
の frontend/src
:
- nano ~/djangoreactproject/frontend/src/CustomersList.js
インポートすることから始めます React
と Component
Reactコンポーネントを作成するには:
import React, { Component } from 'react';
次に、インポートしてインスタンス化します CustomersService
前のステップで作成したモジュール。RESTAPIバックエンドとインターフェイスするメソッドを提供します。
...
import CustomersService from './CustomersService';
const customersService = new CustomersService();
次に、 CustomersList
拡張するコンポーネント Component
RESTAPIを呼び出します。 Reactコンポーネントは、コンポーネントクラスを拡張またはサブクラス化する必要があります。 E6クラスと継承の詳細については、JavaScriptでのクラスの理解に関するチュートリアルを参照してください。
次のコードを追加して、拡張するReactコンポーネントを作成します react.Component
:
...
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;
コンストラクター内で、stateオブジェクトを初期化しています。 これは、空を使用してコンポーネントの状態変数を保持します customers
アレイ。 このアレイは顧客と nextPageURL
これは、バックエンドAPIから取得する次のページのURLを保持します。 また、バインディング nextPage()
と handleDelete()
メソッドから this
したがって、HTMLコードからアクセスできます。
次に、 componentDidMount()
メソッドとへの呼び出し getCustomers()
以内 CustomersList
クラス、中括弧を閉じる前。
The componentDidMount()
methodは、コンポーネントが作成されてDOMに挿入されるときに呼び出されるコンポーネントのライフサイクルメソッドです。 getCustomers()
Customers Serviceオブジェクトを呼び出して、データの最初のページと次のページのリンクをDjangoバックエンドから取得します。
...
componentDidMount() {
var self = this;
customersService.getCustomers().then(function (result) {
self.setState({ customers: result.data, nextPageURL: result.nextlink})
});
}
次に、 handleDelete()
以下の顧客の削除を処理するメソッド componentDidMount()
:
...
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})
});
}
The handleDelete()
メソッドは deleteCustomer()
そのを使用して顧客を削除する方法 pk
(主キー)。 操作が成功した場合、 customers
削除された顧客のアレイは除外されます。
次に、 nextPage()
次のページのデータを取得し、次のページのリンクを更新するメソッド:
...
nextPage(){
var self = this;
customersService.getCustomersByURL(this.state.nextPageURL).then((result) => {
self.setState({ customers: result.data, nextPageURL: result.nextlink})
});
}
The nextPage()
メソッドは getCustomersByURL()
状態オブジェクトから次のページのURLを取得するメソッド。 this.state.nextPageURL
、およびを更新します customers
返されたデータを含む配列。
最後に、コンポーネント render()メソッドを追加します。これにより、コンポーネントの状態から顧客のテーブルがレンダリングされます。
...
render() {
return (
<div className="customers--list">
<table className="table">
<thead key="thead">
<tr>
<th>#</th>
<th>First Name</th>
<th>Last Name</th>
<th>Phone</th>
<th>Email</th>
<th>Address</th>
<th>Description</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{this.state.customers.map( c =>
<tr key={c.pk}>
<td>{c.pk} </td>
<td>{c.first_name}</td>
<td>{c.last_name}</td>
<td>{c.phone}</td>
<td>{c.email}</td>
<td>{c.address}</td>
<td>{c.description}</td>
<td>
<button onClick={(e)=> this.handleDelete(e,c.pk) }> Delete</button>
<a href={"/customer/" + c.pk}> Update</a>
</td>
</tr>)}
</tbody>
</table>
<button className="btn btn-primary" onClick= { this.nextPage }>Next</button>
</div>
);
}
これはファイルの完全な内容です:
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 (
<div className="customers--list">
<table className="table">
<thead key="thead">
<tr>
<th>#</th>
<th>First Name</th>
<th>Last Name</th>
<th>Phone</th>
<th>Email</th>
<th>Address</th>
<th>Description</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{this.state.customers.map( c =>
<tr key={c.pk}>
<td>{c.pk} </td>
<td>{c.first_name}</td>
<td>{c.last_name}</td>
<td>{c.phone}</td>
<td>{c.email}</td>
<td>{c.address}</td>
<td>{c.description}</td>
<td>
<button onClick={(e)=> this.handleDelete(e,c.pk) }> Delete</button>
<a href={"/customer/" + c.pk}> Update</a>
</td>
</tr>)}
</tbody>
</table>
<button className="btn btn-primary" onClick= { this.nextPage }>Next</button>
</div>
);
}
}
export default CustomersList;
これで、 CustomersList
顧客のリストを表示するためのコンポーネント、顧客の作成と更新を処理するコンポーネントを追加できます。
ステップ8—顧客の追加Reactコンポーネントの作成と更新
このステップでは、 CustomerCreateUpdate
コンポーネント。顧客の作成と更新を処理します。 これは、ユーザーが新しい顧客に関するデータを入力するか、既存のエントリを更新するために使用できるフォームを提供することによって行われます。
の frontend/src
、作成する CustomerCreateUpdate.js
ファイル:
- nano ~/djangoreactproject/frontend/src/CustomerCreateUpdate.js
次のコードを追加してReactコンポーネントを作成し、インポートします React
と Component
:
import React, { Component } from 'react';
インポートしてインスタンス化することもできます CustomersService
前のステップで作成したクラス。これは、RESTAPIバックエンドとインターフェイスするメソッドを提供します。
...
import CustomersService from './CustomersService';
const customersService = new CustomersService();
次に、 CustomerCreateUpdate
拡張するコンポーネント Component
顧客を作成および更新するには:
...
class CustomerCreateUpdate extends Component {
constructor(props) {
super(props);
}
}
export default CustomerCreateUpdate;
クラス定義内に、 render()
コンポーネントのメソッド。顧客に関する情報を取得するHTMLフォームをレンダリングします。
...
render() {
return (
<form onSubmit={this.handleSubmit}>
<div className="form-group">
<label>
First Name:</label>
<input className="form-control" type="text" ref='firstName' />
<label>
Last Name:</label>
<input className="form-control" type="text" ref='lastName'/>
<label>
Phone:</label>
<input className="form-control" type="text" ref='phone' />
<label>
Email:</label>
<input className="form-control" type="text" ref='email' />
<label>
Address:</label>
<input className="form-control" type="text" ref='address' />
<label>
Description:</label>
<textarea className="form-control" ref='description' ></textarea>
<input className="btn btn-primary" type="submit" value="Submit" />
</div>
</form>
);
}
フォーム入力要素ごとに、メソッドは ref
フォーム要素の値にアクセスして設定するためのプロパティ。
次に、 render()
メソッド、定義 handleSubmit(event)
ユーザーが送信ボタンをクリックしたときに適切な機能を使用できるようにする方法:
...
handleSubmit(event) {
const { match: { params } } = this.props;
if(params && params.pk){
this.handleUpdate(params.pk);
}
else
{
this.handleCreate();
}
event.preventDefault();
}
...
The handleSubmit(event)
メソッドはフォームの送信を処理し、ルートに応じて、 handleUpdate(pk)
合格した顧客を更新する方法 pk
、 または handleCreate()
新しい顧客を作成する方法。 これらのメソッドはまもなく定義します。
コンポーネントコンストラクタに戻り、新しく追加されたものをバインドします handleSubmit()
方法 this
だからあなたはあなたのフォームでそれにアクセスすることができます:
...
class CustomerCreateUpdate extends Component {
constructor(props) {
super(props);
this.handleSubmit = this.handleSubmit.bind(this);
}
...
次に、を定義します handleCreate()
フォームデータから顧客を作成する方法。 の上に handleSubmit(event)
メソッドには、次のコードを追加します。
...
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.');
});
}
...
The handleCreate()
入力されたデータから顧客を作成するためのメソッドが使用されます。 対応するを呼び出します CustomersService.createCustomer()
顧客を作成するためにバックエンドへの実際のAPI呼び出しを行うメソッド。
次に、以下 handleCreate()
メソッド、定義 handleUpdate(pk)
更新を実装する方法:
...
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.');
});
}
The updateCustomer()
メソッドは、によって顧客を更新します pk
顧客情報フォームからの新しい情報を使用します。 それは customersService.updateCustomer()
方法。
次に、 componentDidMount()
方法。 ユーザーが訪問した場合 customer/:pk
ルートでは、URLの主キーを使用して、顧客に関連する情報をフォームに入力します。 そのために、 getCustomer(pk)
コンポーネントがのライフサイクルイベントにマウントされた後のメソッド componentDidMount()
. このメソッドを追加するには、コンポーネントコンストラクターの下に次のコードを追加します。
...
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;
})
}
}
これはファイルの完全な内容です:
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 (
<form onSubmit={this.handleSubmit}>
<div className="form-group">
<label>
First Name:</label>
<input className="form-control" type="text" ref='firstName' />
<label>
Last Name:</label>
<input className="form-control" type="text" ref='lastName'/>
<label>
Phone:</label>
<input className="form-control" type="text" ref='phone' />
<label>
Email:</label>
<input className="form-control" type="text" ref='email' />
<label>
Address:</label>
<input className="form-control" type="text" ref='address' />
<label>
Description:</label>
<textarea className="form-control" ref='description' ></textarea>
<input className="btn btn-primary" type="submit" value="Submit" />
</div>
</form>
);
}
}
export default CustomerCreateUpdate;
とともに CustomerCreateUpdate
コンポーネントが作成され、メインを更新できます App
作成したさまざまなコンポーネントへのリンクを追加するコンポーネント。
ステップ9—メインアプリコンポーネントを更新する
このセクションでは、 App
前の手順で作成したコンポーネントへのリンクを作成するためのアプリケーションのコンポーネント。
から frontend
フォルダで、次のコマンドを実行して Reactルーターをインストールします。これにより、さまざまなReactコンポーネント間のルーティングとナビゲーションを追加できます。
- cd ~/djangoreactproject/frontend
- npm install --save react-router-dom
次に、開く ~/djangoreactproject/frontend/src/App.js
:
- nano ~/djangoreactproject/frontend/src/App.js
そこにあるものをすべて削除し、次のコードを追加して、ルーティングを追加するために必要なクラスをインポートします。 これらには以下が含まれます BrowserRouter
、ルーターコンポーネントを作成し、 Route
、ルートコンポーネントを作成します。
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 は、HTML5履歴APIを使用してUIをURLと同期させます。
次に、によってラップされる基本コンポーネントを提供する基本レイアウトを作成します。 BrowserRouter
成分:
...
const BaseLayout = () => (
<div className="container-fluid">
<nav className="navbar navbar-expand-lg navbar-light bg-light">
<a className="navbar-brand" href="#">Django React Demo</a>
<button className="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNavAltMarkup" aria-controls="navbarNavAltMarkup" aria-expanded="false" aria-label="Toggle navigation">
<span className="navbar-toggler-icon"></span>
</button>
<div className="collapse navbar-collapse" id="navbarNavAltMarkup">
<div className="navbar-nav">
<a className="nav-item nav-link" href="/">CUSTOMERS</a>
<a className="nav-item nav-link" href="/customer">CREATE CUSTOMER</a>
</div>
</div>
</nav>
<div className="content">
<Route path="/" exact component={CustomersList} />
<Route path="/customer/:pk" component={CustomerCreateUpdate} />
<Route path="/customer/" exact component={CustomerCreateUpdate} />
</div>
</div>
)
を使用します Route
アプリケーションのルートを定義するコンポーネント。 一致するものが見つかったら、ルータがロードする必要のあるコンポーネント。 各ルートには path
照合するパスを指定し、 component
ロードするコンポーネントを指定します。 The exact
プロパティは、ルーターに正確なパスを一致させるように指示します。
最後に、 App
コンポーネント、Reactアプリケーションのルートまたはトップレベルのコンポーネント:
...
class App extends Component {
render() {
return (
<BrowserRouter>
<BaseLayout/>
</BrowserRouter>
);
}
}
export default App;
包みました BaseLayout
コンポーネントと BrowserRouter
私たちのアプリはブラウザで実行することを目的としているため、コンポーネント。
完成したファイルは次のようになります。
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 = () => (
<div className="container-fluid">
<nav className="navbar navbar-expand-lg navbar-light bg-light">
<a className="navbar-brand" href="#">Django React Demo</a>
<button className="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNavAltMarkup" aria-controls="navbarNavAltMarkup" aria-expanded="false" aria-label="Toggle navigation">
<span className="navbar-toggler-icon"></span>
</button>
<div className="collapse navbar-collapse" id="navbarNavAltMarkup">
<div className="navbar-nav">
<a className="nav-item nav-link" href="/">CUSTOMERS</a>
<a className="nav-item nav-link" href="/customer">CREATE CUSTOMER</a>
</div>
</div>
</nav>
<div className="content">
<Route path="/" exact component={CustomersList} />
<Route path="/customer/:pk" component={CustomerCreateUpdate} />
<Route path="/customer/" exact component={CustomerCreateUpdate} />
</div>
</div>
)
class App extends Component {
render() {
return (
<BrowserRouter>
<BaseLayout/>
</BrowserRouter>
);
}
}
export default App;
アプリケーションにルーティングを追加したら、アプリケーションをテストする準備が整いました。 案内する http://localhost:3000
. アプリケーションの最初のページが表示されます。
このアプリケーションを配置すると、CRMアプリケーションのベースができあがります。
結論
このチュートリアルでは、DjangoとReactを使用してデモアプリケーションを作成しました。 DjangoRESTフレームワークを使用してRESTAPIを構築し、Axiosを使用してAPIを使用し、Bootstrap4を使用してCSSのスタイルを設定しました。 このプロジェクトのソースコードは、このGitHubリポジトリにあります。
このチュートリアルのセットアップでは、フロントエンドアプリとバックエンドアプリを別々に使用しました。 ReactをDjangoと統合するための別のアプローチについては、このtutorialとこのtutorialを確認してください。
Djangoを使用したアプリケーションの構築の詳細については、Django開発シリーズをフォローしてください。 公式のDjangoドキュメントもご覧ください。