_著者はhttps://www.brightfunds.org/organizations/open-sourcing-mental-illness-ltd[Open Sourcing Mental Illness Ltd]を選択してhttps://do.co/w4do-ctaの一部として寄付を受け取りました[寄付のために書く]プログラム。

前書き

さまざまな種類のデバイスを使用して、インターネットに接続し、Webを閲覧します。 このため、アプリケーションはさまざまな場所からアクセスできる必要があります。 従来のWebサイトの場合、通常、レスポンシブUIで十分ですが、より複雑なアプリケーションでは他の手法やアーキテクチャを使用する必要があります。 これらには、クライアントサイドWebアプリケーション、プログレッシブWebアプリ(PWA)、またはネイティブモバイルアプリとして実装できる、個別のRESTバックエンドアプリケーションとフロントエンドアプリケーションが含まれます。

より複雑なアプリケーションを構築するときに使用できるツールには次のものがあります。

  • React。開発者がREST APIバックエンドのWebおよびネイティブフロントエンドを構築できるJavaScriptフレームワーク。

  • Django、https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%に準拠した無料のオープンソースPython Webフレームワーク93controller [model view controller(MVC)]ソフトウェアのアーキテクチャパターン。

  • Django REST framework、DjangoでREST APIを構築するための強力で柔軟なツールキット。

このチュートリアルでは、React、Django、およびDjango REST Frameworkを使用して、個別のREST APIバックエンドとフロントエンドを備えた最新のWebアプリケーションを構築します。 DjangoでReactを使用することで、JavaScriptとフロントエンド開発の最新の進歩を活用できます。 組み込みのテンプレートエンジンを使用するDjangoアプリケーションを構築する代わりに、ReactをUIライブラリとして使用し、その仮想Document Object Model(DOM)、宣言型アプローチ、およびデータの変更をすばやくレンダリングするコンポーネントを利用します。

構築するWebアプリケーションは、顧客に関するレコードをデータベースに保存し、CRMアプリケーションの開始点として使用できます。 終了したら、https://getbootstrap.com/ [Bootstrap 4]でスタイル設定されたReactインターフェースを使用して、レコードを作成、読み取り、更新、削除できるようになります。

前提条件

このチュートリアルを完了するには、次のものが必要です。

ステップ1-Python仮想環境の作成と依存関係のインストール

このステップでは、仮想環境を作成し、Django、Django RESTフレームワーク、および「+ django-cors-headers +」など、アプリケーションに必要な依存関係をインストールします。

このアプリケーションでは、DjangoとReactの2つの異なる開発サーバーを使用します。 これらは異なるポートで実行され、2つの別個のドメインとして機能します。 このため、ブラウザーによってブロックされることなくHTTP要求をReactからDjangoに送信するには、https://en.wikipedia.org/wiki/Cross-origin_resource_sharing [cross-origin resource sharing(CORS)]を有効にする必要があります。

ホームディレクトリに移動し、 + venv + Python 3モジュールを使用して仮想環境を作成します。

cd ~
python3 -m venv ./env

`+ source +`を使用して、作成した仮想環境をアクティブ化します。

source env/bin/activate

次に、プロジェクトの依存関係を `+ pip +`でインストールします。 これらには以下が含まれます。

  • * Django *:プロジェクトのWebフレームワーク。

  • * Django RESTフレームワーク*:DjangoでREST APIを構築するサードパーティアプリケーション。

  • * + django-cors-headers + *:CORSを有効にするパッケージ。

Djangoフレームワークをインストールします。

pip install django djangorestframework django-cors-headers

プロジェクトの依存関係をインストールしたら、DjangoプロジェクトとReactフロントエンドを作成できます。

ステップ2-Djangoプロジェクトの作成

この手順では、次のコマンドとユーティリティを使用してDjangoプロジェクトを生成します。

  • * + django-admin startproject + *:https://docs.djangoproject.com/en/2.0/ref/contrib/admin/# [+ django-admin +]はタスクを実行するために使用されるコマンドラインユーティリティですDjangoで。 `+ startproject +`コマンドは新しいDjangoプロジェクトを作成します。

  • * + python manage.py startapp + *: `+ manage.py `は、各Djangoプロジェクトに自動的に追加されるユーティリティスクリプトであり、新しいアプリケーションの作成、データベースの移行、Djangoの提供など、多くの管理タスクを実行します。ローカルでプロジェクト。 その「 startapp +」コマンドは、Djangoプロジェクト内にDjangoアプリケーションを作成します。 Djangoでは、「アプリケーション」という用語は、プロジェクトでいくつかの機能セットを提供するPythonパッケージを表します。

最初に、 `+ django-admin startproject `でDjangoプロジェクトを作成します。 プロジェクトを「+」と呼びます。

django-admin startproject

先に進む前に、 `+ tree +`コマンドを使用してDjangoプロジェクトのディレクトリ構造を見てみましょう。

プロジェクトルート内の `+ djangoreactproject `フォルダーに移動し、 ` tree +`コマンドを実行します。

cd ~/djangoreactproject
tree

次の出力が表示されます。

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

`+〜/ djangoreactproject +`フォルダーはプロジェクトのルートです。 このフォルダー内には、作業に重要なファイルがいくつかあります。

  • * + manage.py + *:多くの管理タスクを実行するユーティリティスクリプト。

  • * + settings.py + *:プロジェクトの設定を変更できるDjangoプロジェクトのメイン設定ファイル。 これらの設定には、プロジェクトの有効なアプリケーションを指定する文字列のhttps://www.digitalocean.com/community/tutorials/understanding-lists-in-python-3[list]である `+ INSTALLED_APPS +`などの変数が含まれます。 Djangoのドキュメントには、https://docs.djangoproject.com/en/2.0/ref/settings/ [利用可能な設定]に関する詳細情報があります。

  • * + urls.py + *:このファイルには、URLパターンと関連ビューのリストが含まれています。 各パターンは、URLと、そのURLに対して呼び出される必要がある関数との間の接続をマップします。 URLとビューの詳細については、https://www.digitalocean.com/community/tutorials/how-to-create-django-views [Djangoビューの作成方法]のチュートリアルを参照してください。

プロジェクトで作業する最初のステップは、前のステップでインストールしたパッケージ(Django RESTフレームワークやDjango CORSパッケージなど)を `+ settings.py `に追加して設定することです。 ` nano +`またはお気に入りのエディターでファイルを開きます:

nano ~/djangoreactproject/djangoreactproject/settings.py

+ INSTALLED_APPS`設定に移動し、リストの一番下に + rest_framework`および `+ corsheaders`アプリケーションを追加します。

〜/ djangoreactproject / djangoreactproject / settings.py

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


]

次に、以前にインストールしたCORSパッケージの `+ corsheaders.middleware.CorsMiddleware `ミドルウェアを ` MIDDLEWARE +`設定に追加します。 この設定は、Webアプリケーションがリクエストまたはレスポンスを処理するたびに処理されるコードを含むPythonクラスである_middlewares_のリストです。

〜/ djangoreactproject / djangoreactproject / settings.py

...

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

]

次に、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 +`ファイルに。 これらの設定をファイルの任意の場所に追加します。

〜/ djangoreactproject / djangoreactproject / settings.py

...





...

https://github.com/ottoyiu/django-cors-headers/#configuration [+ django-cors-headers + docs]で他の設定オプションを見つけることができます。

ファイルを保存し、終了したらエディターを終了します。

まだ `〜/ djangoreactproject +`ディレクトリで、 `+`という新しいDjangoアプリケーションを作成します。

python manage.py startapp

これには、https://www.digitalocean.com/community/tutorials/how-to-create-django-models [models]およびhttps://www.digitalocean.com/community/tutorials/how-to-createが含まれます。 -django-views [views]顧客を管理します。 モデルはアプリケーションデータのフィールドと動作を定義し、ビューはアプリケーションがWeb要求を適切に処理し、必要な応答を返すことを可能にします。

次に、このアプリケーションをプロジェクトの `+ settings.py `ファイルのインストール済みアプリケーションのリストに追加して、Djangoがそれをプロジェクトの一部として認識するようにします。 もう一度 ` settings.py +`を開きます:

nano ~/djangoreactproject/djangoreactproject/settings.py

`+ customers +`アプリケーションを追加します。

〜/ djangoreactproject / djangoreactproject / settings.py

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

]
...

次に、データベースを_migrate_し、ローカル開発サーバーを起動します。 Migrationsは、モデルに加えた変更をデータベーススキーマに伝播するDjangoの方法です。 これらの変更には、たとえば、フィールドの追加やモデルの削除などが含まれます。 モデルと移行の詳細については、https://www.digitalocean.com/community/tutorials/how-to-create-django-models [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ブラウザでこのアドレスに移動すると、次のページが表示されます。

image:https://assets.digitalocean.com/articles/django_react_1604/django_home.png [Djangoデモページ]

この時点で、アプリケーションを実行したままにして、新しいターミナルを開いてプロジェクトの開発を続けます。

ステップ3-Reactフロントエンドの作成

このセクションでは、Reactを使用してプロジェクトのフロントエンドアプリケーションを作成します。

Reactには、https://webpack.js.org/ [Webpack]を直接設定しなくても、Reactプロジェクトをすばやく生成できる公式ユーティリティがあります。 Webpackは、JavaScriptコード、CSS、画像などのWebアセットをバンドルするために使用されるモジュールバンドラーです。 通常、Webpackを使用する前にさまざまな設定オプションを設定する必要がありますが、 `+ create-react-app `ユーティリティのおかげで、さらに制御が必要になるまでWebpackを直接処理する必要はありません。 ` create-react-app `を実行するには、 ` npm +`パッケージバイナリを実行するツールであるhttps://github.com/zkat/npx[npx]を使用できます。

2番目のターミナルで、プロジェクトディレクトリにいることを確認します。

cd ~/djangoreactproject

+ create-react-app`と + npx`を使用して `++`というReactプロジェクトを作成します。

npx create-react-app

次に、Reactアプリケーション内を移動し、開発サーバーを起動します。

cd ~/djangoreactproject/frontend
npm start

アプリケーションは `+ http:// localhost:3000 / +`から実行されます:

image:https://assets.digitalocean.com/articles/django_react_1604/react_home.png [React demo page]

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インターフェースのスタイルを設定するため、CSS設定を管理する `+ frontend / src / App.css +`ファイルに含めます。 ファイルを開きます。

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

次のhttps://www.digitalocean.com/community/tutorials/how-to-import-modules-in-python-3#importing-modules[import]をファイルの先頭に追加します。 ファイルの既存のコンテンツは削除できますが、必須ではありません。

〜/ djangoreactproject / frontend / src / App.css

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

ここで、「+ @ import +」は、他のスタイルシートからスタイルルールをインポートするために使用されるCSS命令です。

バックエンドアプリケーションとフロントエンドアプリケーションの両方を作成したので、顧客モデルといくつかのデモデータを作成しましょう。

ステップ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

ファイルには次のコンテンツが含まれます。

〜/ djangoreactproject / customers / models.py

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

CustomerモデルのAPIは、 + from django.db import models + importステートメントのおかげでファイルに既にインポートされています。 これで、 + models.Model +`を拡張する `+ Customer +`クラスを追加します。 Djangoの各モデルは、https://docs.djangoproject.com/en/2.0/ref/models/instances/#django.db.models.Model [+ django.db.models.Model +`]を拡張するPythonクラスです。

`+ Customer +`モデルには次のデータベースフィールドがあります。

  • * + first_name + *-顧客の名。

  • * + last_name + *-顧客の姓。

  • * + email + *-顧客のメールアドレス。

  • * + phone + *-顧客の電話番号。

  • * + address + *-顧客の住所。

  • * + description + *-顧客の説明。

  • * + createdAt + *-顧客が追加された日付。

モデルの表示方法を定義する関数 `+ str ()+`も追加します。 私たちの場合、それは顧客の名になります。 クラスの構築とオブジェクトの定義の詳細については、https://www.digitalocean.com/community/tutorials/how-to-construct-classes-and-define-objects-in-python-3 [クラスを構築する方法とPython 3でオブジェクトを定義します]。

ファイルに次のコードを追加します。

〜/ 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

次に、データベースを移行してデータベーステーブルを作成します。 https://www.digitalocean.com/community/tutorials/how-to-create-django-models#step-4-%E2%80%94-make-migrations [+ 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

次に、データ移行ファイルを使用して、初期顧客データを作成します。 https://docs.djangoproject.com/en/2.0/topics/migrations/#data-migrations [データ移行ファイル]は、データベース内のデータを追加または変更する移行です。 `+ customers +`アプリケーション用の空のデータ移行ファイルを作成します。

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

移行ファイルの名前とともに次の確認が表示されます。

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

移行ファイルの名前は `+ 0002_customers.py +`であることに注意してください。

次に、 `+ customers +`アプリケーションのmigrationsフォルダー内をナビゲートします。

cd ~/djangoreactproject/customers/migrations

作成された移行ファイルを開きます。

nano 0002_customers.py

これは、ファイルの最初のコンテンツです。

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

from django.db import migrations

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

importステートメントは、データベースを操作するためのクラスを含む組み込みパッケージである + django.db +`から、移行を作成するためのDjango APIである `+ migrations + APIをインポートします。

`+ Migration `クラスは、データベースを移行するときに実行される操作を記述するPythonクラスです。 このクラスは ` migrations.Migration +`を拡張し、2つのリストがあります:

  • * + dependencies + *:依存する移行が含まれます。

  • * + operations + *:移行を適用するときに実行される操作が含まれます。

次に、https://www.digitalocean.com/community/tutorials/how-to-define-functions-in-python-3 [method]を追加して、デモ用の顧客データを作成します。 `+ Migration +`クラスの定義の前に次のメソッドを追加します。

〜/ 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()

...

このメソッドでは、 `+ customers `アプリの ` Customer +`クラスを取得し、データベースに挿入するデモ顧客を作成しています。

新しい顧客の作成を可能にする `+ Customer `クラスを取得するには、 ` apps `オブジェクトの ` get_model()`メソッドを使用します。 ` apps +`オブジェクトは、インストールされているアプリケーションとそのデータベースモデルのhttps://docs.djangoproject.com/en/2.1/ref/applications/#django.apps.apps [レジストリ]を表します。

`+ apps `オブジェクトは、 ` create_data()`の実行に使用するときに ` RunPython()`メソッドから渡されます。 空の ` operations `リストに ` migrations.RunPython()+`メソッドを追加します。

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

...
   operations = [

   ]

`+ RunPython()`は、移行でカスタムPythonコードを実行できるMigrations APIの一部です。 ` operations +`リストは、移行を適用するときにこのメソッドが実行されることを指定します。

これは完全なファイルです。

〜/ 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),
   ]

データ移行の詳細については、https://docs.djangoproject.com/en/2.0/topics/migrations/#data-migrations [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

このプロセスの詳細については、https://www.digitalocean.com/community/tutorials/how-to-create-django-models [Djangoモデルの作成方法]を参照してください。

Customerモデルとデモデータを作成したら、REST APIの構築に進むことができます。

ステップ5-REST APIの作成

このステップでは、Django REST Frameworkを使用してREST APIを作成します。 いくつかの異なる_APIビュー_を作成します。 APIビューはAPIリクエストまたは呼び出しを処理する関数であり、_APIエンドポイント_はRESTシステムとのタッチポイントを表す一意のURLです。 たとえば、ユーザーがAPIエンドポイントにGETリクエストを送信すると、Djangoは対応する関数またはAPIビューを呼び出してリクエストを処理し、可能な結果を​​返します。

また、http://www.django-rest-framework.org/api-guide/serializers/ [serializers]も利用します。 Django REST Frameworkのhttps://docs.djangoproject.com/en/2.0/topics/serialization/[serializer]を使用すると、複雑なモデルインスタンスとQuerySetsをAPI消費のためにJSON形式に変換できます。 シリアライザークラスは、データを解析してDjangoモデルとQuerySetsに逆シリアル化するメカニズムを提供する、別の方向でも機能します。

APIエンドポイントには次のものが含まれます。

  • + api / customers +:このエンドポイントは顧客の作成に使用され、ページ分割された顧客のセットを返します。

  • + api / customers / <pk> +:このエンドポイントは、主キーまたはIDで単一の顧客を取得、更新、削除するために使用されます。

また、対応するエンドポイント(つまり、「+ api / customers 」および「 api / customers / <pk> 」)のプロジェクトの「 urls.py +」ファイルにURLを作成します。

まず、 `+ Customer +`モデルの_serializerクラス_を作成します。

Serializerクラスの追加

`+ Customer `モデルのシリアライザークラスを作成することは、顧客インスタンスとクエリセットをJSONに変換したりJSONから変換したりするために必要です。 シリアライザークラスを作成するには、まず、 ` customers `アプリケーション内で ` serializers.py +`ファイルを作成します。

cd ~/djangoreactproject/customers/
nano serializers.py

次のコードを追加して、シリアライザーAPIと `+ Customer +`モデルをインポートします。

〜/ djangoreactproject / customers / serializers.py

from rest_framework import serializers
from .models import Customer

次に、 `+ serializers.ModelSerializer +`を拡張し、シリアル化されるフィールドを指定するシリアライザークラスを作成します。

〜/ djangoreactproject / customers / serializers.py

...
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 +

これは、ファイルの完全なコンテンツです。

〜/ 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')

シリアライザークラスを作成したので、APIビューを追加できます。

APIビューの追加

このセクションでは、ユーザーがビュー関数に対応するエンドポイントにアクセスしたときにDjangoによって呼び出されるアプリケーションのAPIビューを作成します。

`+〜/ django react project / customers / views.py`を開きます:

nano ~/djangoreactproject/customers/views.py

そこにあるものを削除し、次のインポートを追加します。

〜/ 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およびDjango REST Framework APIとともに、作成したシリアライザーをインポートしています。

次に、POSTおよびGET HTTP要求を処理するためのビューを追加します。

〜/ 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)

最初に、 `+ @ api_view([‘GET’、 ‘POST’])+`デコレータを使用して、GETおよびPOSTリクエストを受け入れることができるAPIビューを作成します。 decoratorは、別の関数を取得して動的に拡張する関数です。

メソッド本体では、 `+ request.method`変数を使用して現在のHTTPメソッドを確認し、リクエストタイプに応じて対応するロジックを実行します。

  • GETリクエストの場合、メソッドはDjango Paginatorを使用してデータをページ分割し、シリアル化後の最初のページのデータ、利用可能な顧客の数を返します、使用可能なページ数、前のページと次のページへのリンク。 Paginatorは、データのリストをページにページ分割し、各ページのアイテムにアクセスするメソッドを提供する組み込みのDjangoクラスです。

  • POSTリクエストの場合、メソッドは受信した顧客データをシリアル化し、シリアライザーオブジェクトの `+ save()`メソッドを呼び出します。 次に、201ステータスコードでhttps://docs.djangoproject.com/en/2.0/ref/request-response/#httpresponse-objects[HttpResponse]のインスタンスであるResponseオブジェクトを返します。 作成する各ビューは、 ` HttpResponse`オブジェクトを返す責任があります。 `+ save()+`メソッドは、シリアル化されたデータをデータベースに保存します。

`+ HttpResponse +`とビューの詳細については、https://www.digitalocean.com/community/tutorials/how-to-create-django-views#step-1-%E2%80%94-createの説明を参照してください。 -view-functions [ビュー関数の作成]。

次に、 + pk +(主キー)で顧客を取得、更新、削除するためのGET、PUT、およびDELETEリクエストの処理を担当するAPIビューを追加します。

〜/ 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)

このメソッドは `+ @ api_view([‘GET’、 ‘PUT’、 ‘DELETE’])+`で装飾されており、GET、PUT、DELETEリクエストを受け入れることができるAPIビューであることを示しています。

`+ request.method +`フィールドのチェックはリクエストメソッドを検証し、その値に応じて正しいロジックを呼び出します:

  • GETリクエストの場合、顧客データはシリアル化され、Responseオブジェクトを使用して送信されます。

  • PUTリクエストの場合、メソッドは新しい顧客データのシリアライザーを作成します。 次に、作成されたシリアライザーオブジェクトの `+ save()+`メソッドを呼び出します。 最後に、更新された顧客とともにResponseオブジェクトを送信します。

  • DELETEリクエストの場合、メソッドは顧客オブジェクトの `+ delete()+`メソッドを呼び出して削除し、データのないResponseオブジェクトを返します。

完成したファイルは次のようになります。

〜/ 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)

これで、エンドポイントの作成に進むことができます。

APIエンドポイントの追加

APIエンドポイントを作成します:顧客のクエリと作成用の + api / customers / +、および + pk +で単一の顧客の取得、更新、削除用の + api / customers / <pk> + ` `。

`+〜/ djangoreactproject / djangoreactproject / urls.py +`を開きます:

nano ~/djangoreactproject/djangoreactproject/urls.py

そこにあるものを残しますが、ファイルの上部にある `+ customers +`ビューにインポートを追加します。

〜/ djangoreactproject / djangoreactproject / urls.py

from django.contrib import admin
from django.urls import path

次に、「+ api / customers / 」および「 api / customers / <pk> 」のURLをhttps://www.digitalocean.com/community/tutorials/how-to-create-django-viewsに追加しますアプリケーションのURLを含む#step-2-%E2%80%94-map-urls-to-views [` urlpatterns +` list]:

〜/ djangoreactproject / djangoreactproject / urls.py

...

urlpatterns = [
   path('admin/', admin.site.urls),


]

RESTエンドポイントを作成したら、それらを使用する方法を見てみましょう。

ステップ6-AxiosでREST APIを使用する

このステップでは、API呼び出しを行うために使用するHTTPクライアントであるhttps://github.com/axios/axios[Axios]をインストールします。 また、作成したAPIエンドポイントを使用するクラスを作成します。

まず、仮想環境を非アクティブ化します。

deactivate

次に、 `+ frontend +`フォルダーに移動します。

cd ~/djangoreactproject/frontend

次を使用して、「+ npm 」から「 axios +」をインストールします。

npm install axios --save

+-save +`オプションは、アプリケーションの `+ package.json`ファイルに + axios`依存関係を追加します。

次に、 `+ CustomersService.js `というJavaScriptファイルを作成します。このファイルには、REST APIを呼び出すコードが含まれます。 これをプロジェクトのアプリケーションコードが存在する ` src +`フォルダー内に作成します。

cd src
nano CustomersService.js

Django REST APIに接続するメソッドを含む次のコードを追加します。

〜/ 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);
   }
}

`+ CustomersService +`クラスは次のAxiosメソッドを呼び出します:

  • + getCustomers()+:顧客の最初のページを取得します。

  • + getCustomersByURL()+:顧客をURLで取得します。 これにより、 `+ / api / customers /?page = 2 +`などのリンクを渡すことにより、顧客の次のページを取得できます。

  • + getCustomer()+:主キーで顧客を取得します。

  • + createCustomer()+:顧客を作成します。

  • + updateCustomer()+:顧客を更新します。

  • + deleteCustomer()+:顧客を削除します。

`+ Customer List`コンポーネントを作成して、React UIインターフェースにAPIのデータを表示できるようになりました。

ステップ7-ReactアプリケーションでAPIからのデータを表示する

このステップでは、 + CustomersList + React _component_を作成します。 ReactコンポーネントはUIの一部を表します。また、UIを独立した再利用可能な部分に分割できます。

まず、 + frontend / src`に + Customers List.js`を作成します。

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

`+ React `と ` Component +`をインポートして、Reactコンポーネントを作成します:

〜/ djangoreactproject / frontend / src / CustomersList.js

import  React, { Component } from  'react';

次に、前のステップで作成した `+ CustomersService +`モジュールをインポートしてインスタンス化します。これは、REST APIバックエンドとインターフェースするメソッドを提供します。

〜/ djangoreactproject / frontend / src / CustomersList.js

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

const  customersService  =  new  CustomersService();

次に、REST APIを呼び出すために + Component +`を拡張する `+ CustomersList +`コンポーネントを作成します。 Reactコンポーネントはhttps://reactjs.org/docs/react-component.html [+ Component +`クラスを拡張またはサブクラス化]する必要があります。 E6クラスと継承の詳細については、https://www.digitalocean.com/community/tutorials/understanding-classes-in-javascript [JavaScriptのクラスを理解する]のチュートリアルを参照してください。

次のコードを追加して、 `+ react.Component`を拡張するReactコンポーネントを作成します。

〜/ 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;

constructor内で、https://reactjs.org/docs/react-component.html#state [+ state +]を初期化していますオブジェクト。 これは、空の + customers + arrayを使用して、コンポーネントの状態変数を保持します。 この配列は顧客と、バックエンドAPIから取得する次のページのURLを保持する + nextPageURL +`を保持します。 また、https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Function/bind [binding] the `+ nextPage()+ and + handleDelete()+ https ://www.digitalocean.com/community/tutorials/understanding-classes-in-javascript#defining-methods [methods]に `+ this +`を追加して、HTMLコードからアクセスできるようにします。

次に、閉じ中括弧の前に、 `+ CustomersList `クラス内で ` componentDidMount()`メソッドと ` getCustomers()+`の呼び出しを追加します。

`+ componentDidMount()`メソッドは、コンポーネントが作成されてDOMに挿入されるときに呼び出されるコンポーネントのライフサイクルメソッドです。 ` getCustomers()+`は、Customers Serviceオブジェクトを呼び出して、Djangoバックエンドからデータの最初のページと次のページのリンクを取得します。

〜/ djangoreactproject / frontend / src / CustomersList.js

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

次に、 `+ componentDidMount()`の下に、顧客の削除を処理する ` handleDelete()+`メソッドを追加します。

〜/ 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})
   });
}

+ handleDelete()+`メソッドは `+ deleteCustomer()+`メソッドを呼び出して、 `+ pk +(主キー)を使用して顧客を削除します。 操作が成功すると、削除された顧客の `+ customers +`配列が除外されます。

次に、 `+ nextPage()+`メソッドを追加して次のページのデータを取得し、次のページのリンクを更新します。

〜/ djangoreactproject / frontend / src / CustomersList.js

...
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 +`配列を返されたデータ。

最後に、コンポーネントの状態から顧客のテーブルをレンダリングするコンポーネントhttps://reactjs.org/docs/react-component.html#render [+ render()+ method]を追加します。

〜/ djangoreactproject / frontend / src / CustomersList.js

...
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>
   );
}

これは、ファイルの完全なコンテンツです。

〜/ 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 (
       <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 `で、 ` Customer Create Update.js`ファイルを作成します。

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

次のコードを追加してReactコンポーネントを作成し、 + React`と + Component`をインポートします:

〜/ djangoreactproject / frontend / src / CustomerCreateUpdate.js

import  React, { Component } from  'react';

前のステップで作成した `+ CustomersService +`クラスをインポートしてインスタンス化することもできます。このクラスは、REST APIバックエンドとインターフェースするメソッドを提供します。

〜/ djangoreactproject / frontend / src / CustomerCreateUpdate.js

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

const  customersService  =  new  CustomersService();

次に、 `+ Component `を拡張して顧客を作成および更新する ` CustomerCreateUpdate +`コンポーネントを作成します。

〜/ djangoreactproject / frontend / src / CustomerCreateUpdate.js

...
class  CustomerCreateUpdate  extends  Component {

   constructor(props) {
       super(props);
   }

}
export default CustomerCreateUpdate;

クラス定義内に、コンポーネントに関する `+ render()+`メソッドを追加します。これにより、顧客に関する情報を取得するHTMLフォームがレンダリングされます。

〜/ djangoreactproject / frontend / src / CustomerCreateUpdate.js

...
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)+`メソッドを定義します。

〜/ 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();
}

...

`+ handleSubmit(event)`メソッドはフォームの送信を処理し、ルートに応じて、 ` handleUpdate(pk)`メソッドを呼び出して、渡された ` pk `または ` handleCreateで顧客を更新します()+ `新しい顧客を作成する方法。 これらのメソッドをすぐに定義します。

コンポーネントコンストラクターに戻り、新しく追加した `+ handleSubmit()`メソッドを ` this +`にバインドして、フォームでアクセスできるようにします。

〜/ djangoreactproject / frontend / src / CustomerCreateUpdate.js

...
class CustomerCreateUpdate extends Component {

constructor(props) {
   super(props);

}
...

次に、 `+ handleCreate()`メソッドを定義して、フォームデータから顧客を作成します。 ` handleSubmit(event)+`メソッドの上に、次のコードを追加します。

〜/ 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.');
       });
}

...

入力されたデータから顧客を作成するには、 `+ handleCreate()`メソッドを使用します。 対応する ` CustomersService.createCustomer()+`メソッドを呼び出して、バックエンドへの実際のAPI呼び出しを行い、顧客を作成します。

次に、 `+ handleCreate()`メソッドの下で、 ` handleUpdate(pk)+`メソッドを定義して更新を実装します。

〜/ 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.');
   });
}

`+ updateCustomer()`メソッドは、顧客情報フォームからの新しい情報を使用して、 ` pk `によって顧客を更新します。 ` customersService.updateCustomer()+`メソッドを呼び出します。

次に、 `+ componentDidMount()`メソッドを追加します。 ユーザーが ` customer /:pk `ルートにアクセスした場合、URLのプライマリキーを使用して顧客に関連する情報をフォームに入力します。 これを行うには、コンポーネントが ` componentDidMount()`のライフサイクルイベントにマウントされた後に ` getCustomer(pk)+`メソッドを追加します。 このメソッドを追加するには、コンポーネントコンストラクターの下に次のコードを追加します。

〜/ 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;
       })
   }
}

これは、ファイルの完全なコンテンツです。

〜/ 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 (
         <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 +`フォルダーから、次のコマンドを実行してhttps://www.npmjs.com/package/react-router-dom[React Router]をインストールします。これにより、さまざまなReactコンポーネント間のルーティングとナビゲーションを追加できます。

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

次に、 `+〜/ django react project / frontend / src / App.js`を開きます。

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

そこにあるものをすべて削除し、次のコードを追加して、ルーティングの追加に必要なクラスをインポートします。 これらには、ルーターコンポーネントを作成する `+ BrowserRouter `と、ルートコンポーネントを作成する ` Route +`が含まれます。

〜/ 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';

https://reacttraining.com/react-router/web/api/BrowserRouter [+ BrowserRouter +]は、https://developer.mozilla.org/en-US/docs/Webを使用して、UIをURLと同期させます/ API / History_API [HTML5 history API]。

次に、 `+ BrowserRouter +`コンポーネントによってラップされるベースコンポーネントを提供するベースレイアウトを作成します。

〜/ djangoreactproject / frontend / src / App.js

...

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 +`コンポーネントを作成します。

〜/ djangoreactproject / frontend / src / App.js

...

class  App  extends  Component {

render() {
   return (
   <BrowserRouter>
       <BaseLayout/>
   </BrowserRouter>
   );
}
}
export  default  App;

アプリはブラウザーで実行するため、 `+ BaseLayout `コンポーネントを ` BrowserRouter +`コンポーネントでラップしました。

完成したファイルは次のようになります。

〜/ 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 = () => (
 <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 +`に移動します。 アプリケーションの最初のページが表示されるはずです。

image:https://assets.digitalocean.com/articles/django_react_1604/django_react_app.png [アプリケーションのホームページ]

このアプリケーションを配置すると、CRMアプリケーションのベースができました。

結論

このチュートリアルでは、DjangoとReactを使用してデモアプリケーションを作成しました。 Django RESTフレームワークを使用してREST APIを作成し、Axiosを使用してAPIを作成し、Bootstrap 4を使用してCSSをスタイルしました。 このプロジェクトのソースコードは、https://github.com/techiediaries/django-react [GitHubリポジトリ]にあります。

このチュートリアルのセットアップでは、フロントエンドアプリとバックエンドアプリを別々に使用しました。 ReactとDjangoを統合する別のアプローチについては、https://www.techiediaries.com/django-react-rest/ [tutorial]およびこのhttp://v1k45.com/blog/modern-django-part-1を確認してください。 -setting-up-django-and-react / [チュートリアル]。

Djangoを使用したアプリケーションの構築の詳細については、https://www.digitalocean.com/community/tutorial_series/django-development [Django開発シリーズ]を参照してください。 https://docs.djangoproject.com/en/2.1/ [公式Djangoドキュメント]もご覧ください。