著者は、 Write for DOnations プログラムの一環として、 Open Sourcing Mental IllnessLtdを選択して寄付を受け取りました。
序章
人々はさまざまな種類のデバイスを使用してインターネットに接続し、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を搭載した開発マシン。
- Python3のインストール方法とUbuntu18.04でのローカルプログラミング環境のセットアップ方法の手順1と2に従って、Python 3、
pip
、およびvenv
をマシンにインストールします。 - Node.js6以降および
npm
5.2以降がマシンにインストールされている。 PPAからインストールする場合は、 Ubuntu18.04にNode.jsをインストールする方法の手順に従って両方をインストールできます。
ステップ1—Python仮想環境の作成と依存関係のインストール
このステップでは、仮想環境を作成し、Django、Django RESTフレームワーク、django-cors-headers
などのアプリケーションに必要な依存関係をインストールします。
このアプリケーションでは、DjangoとReactに2つの異なる開発サーバーを使用します。 これらは異なるポートで実行され、2つの別個のドメインとして機能します。 このため、クロスオリジンリソースシェアリング(CORS)を有効にして、ブラウザーによってブロックされることなくReactからDjangoにHTTPリクエストを送信する必要があります。
ホームディレクトリに移動し、venv
Python3モジュールを使用して仮想環境を作成します。
- 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でタスクを実行するために使用されるコマンドラインユーティリティです。
startproject
コマンドは、新しいDjangoプロジェクトを作成します。 -
python manage.py startapp myapp :
manage.py
は、各Djangoプロジェクトに自動的に追加されるユーティリティスクリプトであり、新しいアプリケーションの作成、データベースの移行、サービスの提供など、さまざまな管理タスクを実行します。 Djangoプロジェクトをローカルで。 そのstartapp
コマンドは、Djangoプロジェクト内にDjangoアプリケーションを作成します。 Djangoでは、 application という用語は、プロジェクトにいくつかの機能セットを提供するPythonパッケージを表します。
まず、django-admin startproject
を使用してDjangoプロジェクトを作成します。 プロジェクトをdjangoreactproject
と呼びます。
- django-admin startproject djangoreactproject
先に進む前に、tree
コマンドを使用してDjangoプロジェクトのディレクトリ構造を見てみましょう。
ヒント: tree
is a useful command for viewing file and directory structures from the command line. You can install it with the following command:
- 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
~/djangoreactproject
フォルダーはプロジェクトのルートです。 このフォルダ内には、作業に重要ないくつかのファイルがあります。
- manage.py :いくつかの管理タスクを実行するユーティリティスクリプト。
- settings.py :プロジェクトの設定を変更できるDjangoプロジェクトのメイン構成ファイル。 これらの設定には、
INSTALLED_APPS
、プロジェクトで有効なアプリケーションを指定する文字列のlistなどの変数が含まれます。 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'
]
次に、以前にインストールしたCORSパッケージのcorsheaders.middleware.CorsMiddleware
ミドルウェアをMIDDLEWARE
設定に追加します。 この設定は、ミドルウェアのリストです。これは、Webアプリケーションが要求または応答を処理するたびに処理されるコードを含むPythonクラスです。
...
MIDDLEWARE = [
...
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'corsheaders.middleware.CorsMiddleware'
]
次に、CORSを有効にできます。 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
ディレクトリに、customers
という新しいDjangoアプリケーションを作成します。
- 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
を実行するには、npm
パッケージバイナリを実行するツールであるnpxを使用できます。
2番目のターミナルで、プロジェクトディレクトリにいることを確認します。
- cd ~/djangoreactproject
create-react-app
とnpx
を使用して、frontend
というReactプロジェクトを作成します。
- 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
このアプリケーションはBootstrap4を使用してReactインターフェースのスタイルを設定するため、CSS設定を管理するfrontend/src/App.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
ディレクトリに移動し、アプリケーションのモデルを保持するPythonファイルであるmodels.py
を開きます。
- cd ~/djangoreactproject/customers/
- nano models.py
このファイルには、次の内容が含まれます。
from django.db import models
# Create your models here.
from django.db import models
importステートメントのおかげで、CustomerモデルのAPIはすでにファイルにインポートされています。 次に、models.Model
を拡張するCustomer
クラスを追加します。 Djangoの各モデルは、django.db.models.Modelを拡張するPythonクラスです。
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ステートメントは、データベースを操作するためのクラスを含む組み込みパッケージであるdjango.db
から、移行を作成するためのDjangoAPIであるmigrations
APIをインポートします。
Migration
クラスは、データベースの移行時に実行される操作を記述する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="customer001@email.com", phone="00000000", address="Customer 000 Address", description= "Customer 001 description").save()
...
このメソッドでは、customers
アプリのCustomer
クラスを取得し、データベースに挿入するデモカスタマーを作成します。
新しい顧客の作成を可能にするCustomer
クラスを取得するには、apps
オブジェクトのget_model()
メソッドを使用します。 apps
オブジェクトは、インストールされているアプリケーションとそのデータベースモデルのレジストリを表します。
apps
オブジェクトは、create_data()
を実行するために使用すると、RunPython()
メソッドから渡されます。 migrations.RunPython()
メソッドを空のoperations
リストに追加します。
...
operations = [
migrations.RunPython(create_data),
]
RunPython()
は、移行でカスタムPythonコードを実行できるようにするMigrationsAPIの一部です。 operations
リストは、移行を適用するときにこのメソッドが実行されることを指定しています。
これは完全なファイルです:
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="customer001@email.com", 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によって単一の顧客を取得、更新、および削除するために使用されます。
また、プロジェクトのurls.py
ファイルに対応するエンドポイント(つまり、api/customers
およびapi/customers/<pk>
)のURLを作成します。
Customer
モデルのシリアライザークラスを作成することから始めましょう。
シリアライザークラスの追加
Customer
モデルのシリアライザークラスを作成することは、顧客インスタンスとQuerySetをJSONとの間で変換するために必要です。 シリアライザークラスを作成するには、最初にcustomers
アプリケーション内にserializers.py
ファイルを作成します。
- 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')
Meta
クラスは、シリアル化するモデルとフィールドを指定します: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およびDjangoRESTFrameworkAPIとともにインポートしています。
次に、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
オブジェクトを再作成する責任があります。save()
メソッドは、シリアル化されたデータをデータベースに保存します。
HttpResponse
とビューの詳細については、ビュー関数の作成に関するこの説明を参照してください。
次に、pk
(主キー)による顧客の取得、更新、および削除のためのGET、PUT、およびDELETE要求の処理を担当するAPIビューを追加します。
...
@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リクエストの場合、メソッドはcustomerオブジェクトの
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/
と、pk
による単一の顧客の取得、更新、または削除用のapi/customers/<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を、アプリケーションのURLを含むurlpatternsリストに追加します。
...
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
以下を使用して、npm
からaxios
をインストールします。
- npm install axios --save
--save
オプションは、axios
依存関係をアプリケーションのpackage.json
ファイルに追加します。
次に、CustomersService.js
というJavaScriptファイルを作成します。このファイルには、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);
}
}
CustomersService
クラスは、次のAxiosメソッドを呼び出します。
getCustomers()
:顧客の最初のページを取得します。getCustomersByURL()
:URLで顧客を取得します。 これにより、/api/customers/?page=2
などのリンクを渡すことで、顧客の次のページを取得できます。getCustomer()
:主キーで顧客を取得します。createCustomer()
:顧客を作成します。updateCustomer()
:顧客を更新します。deleteCustomer()
:顧客を削除します。
CustomersList
コンポーネントを作成することで、APIからのデータをReactUIインターフェースに表示できるようになりました。
ステップ7—ReactアプリケーションでAPIからのデータを表示する
このステップでは、CustomersList
Reactコンポーネントを作成します。 ReactコンポーネントはUIの一部を表します。 また、UIを独立した再利用可能な部分に分割することもできます。
frontend/src
にCustomersList.js
を作成することから始めます。
- nano ~/djangoreactproject/frontend/src/CustomersList.js
React
とComponent
をインポートして、Reactコンポーネントを作成することから始めます。
import React, { Component } from 'react';
次に、前の手順で作成したCustomersService
モジュールをインポートしてインスタンス化します。これにより、RESTAPIバックエンドとインターフェイスするメソッドが提供されます。
...
import CustomersService from './CustomersService';
const customersService = new CustomersService();
次に、Component
を拡張してRESTAPIを呼び出すCustomersList
コンポーネントを作成します。 Reactコンポーネントは、コンポーネントクラスを拡張またはサブクラス化する必要があります。 E6クラスと継承の詳細については、JavaScriptでのクラスの理解に関するチュートリアルを参照してください。
次のコードを追加して、react.Component
を拡張するReactコンポーネントを作成します。
...
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
arrayを使用してコンポーネントの状態変数を保持します。 この配列は、顧客と、バックエンドAPIから取得する次のページのURLを保持するnextPageURL
を保持します。 また、バインディング nextPage()
およびhandleDelete()
メソッドからthis
にバインドしているため、HTMLコードからアクセスできます。
次に、componentDidMount()
メソッドと、CustomersList
クラス内のgetCustomers()
の呼び出しを追加してから、中括弧を閉じます。
componentDidMount()
メソッドは、コンポーネントが作成されてDOMに挿入されるときに呼び出されるコンポーネントのライフサイクルメソッドです。 getCustomers()
は、Customers Serviceオブジェクトを呼び出して、データの最初のページと次のページのリンクをDjangoバックエンドから取得します。
...
componentDidMount() {
var self = this;
customersService.getCustomers().then(function (result) {
self.setState({ customers: result.data, nextPageURL: result.nextlink})
});
}
次に、componentDidMount()
の下に、顧客の削除を処理するhandleDelete()
メソッドを追加します。
...
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})
});
}
handleDelete()
メソッドは、deleteCustomer()
メソッドを呼び出し、pk
(主キー)を使用して顧客を削除します。 操作が成功すると、削除された顧客のcustomers
アレイが除外されます。
次に、nextPage()
メソッドを追加して、次のページのデータを取得し、次のページのリンクを更新します。
...
nextPage(){
var self = this;
customersService.getCustomersByURL(this.state.nextPageURL).then((result) => {
self.setState({ customers: result.data, nextPageURL: result.nextlink})
});
}
nextPage()
メソッドは、getCustomersByURL()
メソッドを呼び出します。このメソッドは、状態オブジェクトthis.state.nextPageURL
から次のページのURLを取得し、返されたデータで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
とComponent
をインポートしてReactコンポーネントを作成します。
import React, { Component } from 'react';
前の手順で作成したCustomersService
クラスをインポートしてインスタンス化することもできます。これにより、RESTAPIバックエンドとインターフェイスするメソッドが提供されます。
...
import CustomersService from './CustomersService';
const customersService = new CustomersService();
次に、Component
を拡張するCustomerCreateUpdate
コンポーネントを作成して、顧客を作成および更新します。
...
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();
}
...
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.');
});
}
...
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.');
});
}
updateCustomer()
メソッドは、顧客情報フォームからの新しい情報を使用して、pk
によって顧客を更新します。 customersService.updateCustomer()
メソッドを呼び出します。
次に、componentDidMount()
メソッドを追加します。 ユーザーがcustomer/:pk
ルートにアクセスした場合、URLの主キーを使用して、顧客に関連する情報をフォームに入力します。 これを行うには、コンポーネントがcomponentDidMount()
のライフサイクルイベントにマウントされた後に、getCustomer(pk)
メソッドを追加できます。 このメソッドを追加するには、コンポーネントコンストラクターの下に次のコードを追加します。
...
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
が必要です。 exact
プロパティは、ルーターに正確なパスを一致させるように指示します。
最後に、ReactアプリケーションのルートまたはトップレベルコンポーネントであるApp
コンポーネントを作成します。
...
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ドキュメントもご覧ください。