DjangoとReactを使用してTo-Doアプリケーションを構築する方法
序章
このチュートリアルでは、DjangoとReactを使用してTo-Doアプリケーションを構築します。
Reactは、SPA(シングルページアプリケーション)を開発するためのJavaScriptフレームワークです。 堅実なドキュメントとその周りの活気に満ちたエコシステムがあります。
Djangoは、Web開発の一般的な方法を簡素化するPythonWebフレームワークです。 Djangoは信頼性が高く、一般的な開発ニーズをサポートする安定したライブラリの活気に満ちたエコシステムも備えています。
このアプリケーションでは、Reactはフロントエンドまたはクライアント側のフレームワークとして機能し、ユーザーインターフェースを処理し、Django RESTフレームワーク(DRF)を使用して構築されたAPIであるDjangoバックエンドへのリクエストを介してデータを取得および設定します。
このチュートリアルを終了すると、完全に機能するアプリケーションができあがります。
注:このチュートリアルのソースコードはGitHubで入手できます。
警告:このチュートリアルで提供されるコードは教育目的であり、本番環境での使用を目的としたものではありません。
このアプリケーションを使用すると、ユーザーはタスクを作成して、それらを完了または未完了としてマークできます。
前提条件
このチュートリアルに従うには、次のことを行う必要があります。
このチュートリアルはPythonv3.9.1で検証されました pip
v20.2.4、Django v3.1.6、 djangorestframework
v3.12.2、 django-cors-headers
v3.7.0、ノードv15.8.0、 npm
v7.5.4、React v17.0.1、および axios
v0.21.0。
ステップ1—バックエンドを設定する
このセクションでは、新しいプロジェクトディレクトリを作成し、Djangoをインストールします。
新しいターミナルウィンドウを開き、次のコマンドを実行して新しいプロジェクトディレクトリを作成します。
- mkdir django-todo-react
次に、ディレクトリに移動します。
- cd django-todo-react
次に、を使用してPipenvをインストールします pip
:
- pip install pipenv
注:インストールによっては、次を使用する必要がある場合があります pip3
それ以外の pip
.
そして、新しい仮想環境をアクティブ化します。
- pipenv shell
Pipenvを使用してDjangoをインストールします。
- pipenv install django
次に、という新しいプロジェクトを作成します backend
:
- django-admin startproject backend
次に、新しく作成されたバックエンドディレクトリに移動します。
- cd backend
と呼ばれる新しいアプリケーションを起動します todo
:
python manage.py startapp todo
移行を実行します。
python manage.py migrate
そして、サーバーを起動します。
python manage.py runserver
案内する http://localhost:8000
Webブラウザで:
この時点で、Djangoアプリケーションのインスタンスが正常に実行されていることがわかります。 終了したら、サーバーを停止できます(CONTROL+C
また CTRL+C
).
登録する todo
応用
バックエンドのセットアップが完了したので、登録を開始できます。 todo
Djangoが認識できるようにインストールされたアプリとしてのアプリケーション。
を開きます backend/settings.py
コードエディタでファイルを作成し、追加します todo
に INSTALLED_APPS
:
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'todo',
]
次に、変更を保存します。
の定義 Todo
モデル
モデルを作成して、 Todo
アイテムはデータベースに保存する必要があります。
を開きます todo/models.py
コードエディタでファイルを作成し、次のコード行を追加します。
from django.db import models
# Create your models here.
class Todo(models.Model):
title = models.CharField(max_length=120)
description = models.TextField()
completed = models.BooleanField(default=False)
def _str_(self):
return self.title
上記のコードスニペットは、Todoモデルの3つのプロパティについて説明しています。
title
description
completed
The completed
プロパティは、タスクのステータスです。 タスクはいつでも完了するか、完了しないかのいずれかです。 あなたが作成したので Todo
モデルの場合、移行ファイルを作成する必要があります。
- python manage.py makemigrations todo
そして、変更をデータベースに適用します。
- python manage.py migrate todo
CRUD操作がで動作することを確認するためにテストできます Todo
Djangoがデフォルトで提供する管理インターフェースを使用して作成したモデル。
を開きます todo/admin.py
コードエディタでファイルを作成し、次のコード行を追加します。
from django.contrib import admin
from .models import Todo
class TodoAdmin(admin.ModelAdmin):
list_display = ('title', 'description', 'completed')
# Register your models here.
admin.site.register(Todo, TodoAdmin)
次に、変更を保存します。
管理者インターフェースにアクセスするには、「スーパーユーザー」アカウントを作成する必要があります。 ターミナルで次のコマンドを実行します。
- python manage.py createsuperuser
スーパーユーザーのユーザー名、電子メール、およびパスワードを入力するように求められます。 管理ダッシュボードにログインするために必要になるため、覚えておくことができる詳細を必ず入力してください。
サーバーをもう一度起動します。
- python manage.py runserver
案内する http://localhost:8000/admin
Webブラウザで。 そして、以前に作成したユーザー名とパスワードでログインします。
作成、編集、および削除できます Todo
このインターフェースを使用するアイテム:
このインターフェースを試した後、サーバーを停止できます(CONTROL+C
また CTRL+C
).
ステップ2—APIを設定する
このセクションでは、DjangoRESTフレームワークを使用してAPIを作成します。
をインストールします djangorestframework
と django-cors-headers
Pipenvの使用:
- pipenv install djangorestframework django-cors-headers
追加する必要があります rest_framework
と corsheaders
インストールされているアプリケーションのリストに移動します。 を開きます backend/settings.py
コードエディタでファイルを作成し、 INSTALLED_APPS
と MIDDLEWARE
セクション:
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'corsheaders',
'rest_framework',
'todo',
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'corsheaders.middleware.CorsMiddleware',
]
次に、これらのコード行をの下部に追加します backend/settings.py
ファイル:
CORS_ORIGIN_WHITELIST = [
'http://localhost:3000'
]
django-cors-headers
は、CORSルールが原因で通常発生するエラーを防ぐPythonライブラリです。 の中に CORS_ORIGIN_WHITELIST
コード、ホワイトリストに登録しました localhost:3000
アプリケーションのフロントエンド(そのポートで提供される)がAPIと対話するようにするためです。
作成 serializers
フロントエンドが受信したデータを処理できるように、モデルインスタンスをJSONに変換するシリアライザーが必要になります。
作成する todo/serializers.py
コードエディタでファイルします。 を開きます serializers.py
ファイルを作成し、次のコード行で更新します。
from rest_framework import serializers
from .models import Todo
class TodoSerializer(serializers.ModelSerializer):
class Meta:
model = Todo
fields = ('id', 'title', 'description', 'completed')
このコードは、操作するモデルとJSONに変換するフィールドを指定します。
ビューの作成
を作成する必要があります TodoView
のクラス todo/views.py
ファイル。
を開きます todo/views.py
コードエディタでファイルを作成し、次のコード行を追加します。
from django.shortcuts import render
from rest_framework import viewsets
from .serializers import TodoSerializer
from .models import Todo
# Create your views here.
class TodoView(viewsets.ModelViewSet):
serializer_class = TodoSerializer
queryset = Todo.objects.all()
The viewsets
基本クラスは、デフォルトでCRUD操作の実装を提供します。 このコードは、 serializer_class
そしてその queryset
.
を開きます backend/urls.py
コードエディタでファイルを作成し、内容を次のコード行に置き換えます。
from django.contrib import admin
from django.urls import path, include
from rest_framework import routers
from todo import views
router = routers.DefaultRouter()
router.register(r'todos', views.TodoView, 'todo')
urlpatterns = [
path('admin/', admin.site.urls),
path('api/', include(router.urls)),
]
このコードは、APIのURLパスを指定します。 これは、APIの構築を完了する最後のステップでした。
これで、CRUD操作を実行できます。 Todo
モデル。 routerクラスを使用すると、次のクエリを実行できます。
/todos/
-すべてのリストを返しますTodo
アイテム。CREATE
とREAD
ここで操作を実行できます。/todos/id
-シングルを返しますTodo
を使用したアイテムid
主キー。UPDATE
とDELETE
ここで操作を実行できます。
サーバーを再起動しましょう:
- python manage.py runserver
案内する http://localhost:8000/api/todos
Webブラウザで:
あなたはできる CREATE
インターフェイスを使用した新しいTodoアイテム:
Todoアイテムが正常に作成されると、正常な応答が表示されます。
実行することもできます DELETE
と UPDATE
特定の操作 Todo
を使用したアイテム id
主キー。 アドレス構造を使用する /api/todos/{id}
と提供します id
.
追加 1
URLに移動して、Todoアイテムを調べます。 id
「1」の。 案内する http://localhost:8000/api/todos/1
Webブラウザで:
これで、アプリケーションのバックエンドの構築が完了しました。
ステップ3—フロントエンドの設定
アプリケーションのバックエンドが完成したので、フロントエンドを作成し、作成したインターフェイスを介してバックエンドと通信させることができます。
まず、新しいターミナルウィンドウを開き、に移動します django-todo-react
プロジェクトディレクトリ。
フロントエンドを設定するために、このチュートリアルはCreateReactAppに依存します。 使用するにはいくつかのアプローチがあります create-react-app
. 1つのアプローチは使用することです npx
パッケージを実行してプロジェクトを作成するには:
- npx create-react-app frontend
Create React Appを使用してReactプロジェクトをセットアップする方法を読むと、このアプローチの詳細を学ぶことができます。
プロジェクトが作成されたら、新しく作成されたものに変更できます frontend
ディレクトリ:
- cd frontend
次に、アプリケーションを起動します。
- npm start
Webブラウザが開きます http://localhost:3000
デフォルトのCreateReactApp画面が表示されます。
次に、インストールします bootstrap
と reactstrap
ユーザーインターフェイスツールを提供します。
- npm install bootstrap@4.6.0 reactstrap@8.9.0 --legacy-peer-deps
注:遭遇する可能性があります unable to resolve dependency tree
React、Bootstrap、およびReactstrapのバージョンに応じてエラーが発生します。
改訂時の最新バージョン popper.js
非推奨になり、React17+と競合します。 これは既知の問題であり、 --legacy-peer-deps
インストール時のオプション。
開ける index.js
コードエディタで追加します bootstrap.min.css
:
import React from 'react';
import ReactDOM from 'react-dom';
import 'bootstrap/dist/css/bootstrap.css';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
この手順で問題が発生した場合は、ブートストラップを追加するための公式ドキュメントを参照してください。
開ける App.js
コードエディタで、次のコード行を追加します。
import React, { Component } from "react";
const todoItems = [
{
id: 1,
title: "Go to Market",
description: "Buy ingredients to prepare dinner",
completed: true,
},
{
id: 2,
title: "Study",
description: "Read Algebra and History textbook for the upcoming test",
completed: false,
},
{
id: 3,
title: "Sammy's books",
description: "Go to library to return Sammy's books",
completed: true,
},
{
id: 4,
title: "Article",
description: "Write article on how to use Django with React",
completed: false,
},
];
class App extends Component {
constructor(props) {
super(props);
this.state = {
viewCompleted: false,
todoList: todoItems,
};
}
displayCompleted = (status) => {
if (status) {
return this.setState({ viewCompleted: true });
}
return this.setState({ viewCompleted: false });
};
renderTabList = () => {
return (
<div className="nav nav-tabs">
<span
className={this.state.viewCompleted ? "nav-link active" : "nav-link"}
onClick={() => this.displayCompleted(true)}
>
Complete
</span>
<span
className={this.state.viewCompleted ? "nav-link" : "nav-link active"}
onClick={() => this.displayCompleted(false)}
>
Incomplete
</span>
</div>
);
};
renderItems = () => {
const { viewCompleted } = this.state;
const newItems = this.state.todoList.filter(
(item) => item.completed == viewCompleted
);
return newItems.map((item) => (
<li
key={item.id}
className="list-group-item d-flex justify-content-between align-items-center"
>
<span
className={`todo-title mr-2 ${
this.state.viewCompleted ? "completed-todo" : ""
}`}
title={item.description}
>
{item.title}
</span>
<span>
<button
className="btn btn-secondary mr-2"
>
Edit
</button>
<button
className="btn btn-danger"
>
Delete
</button>
</span>
</li>
));
};
render() {
return (
<main className="container">
<h1 className="text-white text-uppercase text-center my-4">Todo app</h1>
<div className="row">
<div className="col-md-6 col-sm-10 mx-auto p-0">
<div className="card p-3">
<div className="mb-4">
<button
className="btn btn-primary"
>
Add task
</button>
</div>
{this.renderTabList()}
<ul className="list-group list-group-flush border-top-0">
{this.renderItems()}
</ul>
</div>
</div>
</div>
</main>
);
}
}
export default App;
このコードには、4つのアイテムのハードコードされた値が含まれています。 これらは、アイテムがバックエンドからフェッチされるまでの一時的な値になります。
The renderTabList()
関数は、表示されるアイテムのセットを制御するのに役立つ2つのスパンをレンダリングします。 完了タブをクリックすると、完了したタスクが表示されます。 不完全タブをクリックすると、不完全なタスクが表示されます。
変更を保存し、Webブラウザでアプリケーションを確認します。
タスクの追加や編集などのアクションを処理するには、モーダルコンポーネントを作成する必要があります。
まず、作成します components
のフォルダ src
ディレクトリ:
- mkdir src/components
次に、を作成します Modal.js
ファイルを作成し、コードエディタで開きます。 次のコード行を追加します。
import React, { Component } from "react";
import {
Button,
Modal,
ModalHeader,
ModalBody,
ModalFooter,
Form,
FormGroup,
Input,
Label,
} from "reactstrap";
export default class CustomModal extends Component {
constructor(props) {
super(props);
this.state = {
activeItem: this.props.activeItem,
};
}
handleChange = (e) => {
let { name, value } = e.target;
if (e.target.type === "checkbox") {
value = e.target.checked;
}
const activeItem = { ...this.state.activeItem, [name]: value };
this.setState({ activeItem });
};
render() {
const { toggle, onSave } = this.props;
return (
<Modal isOpen={true} toggle={toggle}>
<ModalHeader toggle={toggle}>Todo Item</ModalHeader>
<ModalBody>
<Form>
<FormGroup>
<Label for="todo-title">Title</Label>
<Input
type="text"
id="todo-title"
name="title"
value={this.state.activeItem.title}
onChange={this.handleChange}
placeholder="Enter Todo Title"
/>
</FormGroup>
<FormGroup>
<Label for="todo-description">Description</Label>
<Input
type="text"
id="todo-description"
name="description"
value={this.state.activeItem.description}
onChange={this.handleChange}
placeholder="Enter Todo description"
/>
</FormGroup>
<FormGroup check>
<Label check>
<Input
type="checkbox"
name="completed"
checked={this.state.activeItem.completed}
onChange={this.handleChange}
/>
Completed
</Label>
</FormGroup>
</Form>
</ModalBody>
<ModalFooter>
<Button
color="success"
onClick={() => onSave(this.state.activeItem)}
>
Save
</Button>
</ModalFooter>
</Modal>
);
}
}
このコードは CustomModal
クラスとそれはから派生したモーダルコンポーネントをネストします reactstrap
図書館。
このコードは、次の形式で3つのフィールドも定義しました。
title
description
completed
これらは、バックエンドのTodoモデルのプロパティとして定義したものと同じフィールドです。
The CustomModal
受け取る activeItem
, toggle
、 と onSave
小道具として:
activeItem
編集するTodoアイテムを表します。toggle
モーダルの状態を制御するために使用される関数です(つまり、モーダルを開いたり閉じたりします)。onSave
Todoアイテムの編集された値を保存するために呼び出される関数です。
次に、をインポートします CustomModal
コンポーネントを App.js
ファイル。
再訪 src/App.js
コードエディタでファイルを作成し、内容全体を次のコード行に置き換えます。
import React, { Component } from "react";
import Modal from "./components/Modal";
const todoItems = [
{
id: 1,
title: "Go to Market",
description: "Buy ingredients to prepare dinner",
completed: true,
},
{
id: 2,
title: "Study",
description: "Read Algebra and History textbook for the upcoming test",
completed: false,
},
{
id: 3,
title: "Sammy's books",
description: "Go to library to return Sammy's books",
completed: true,
},
{
id: 4,
title: "Article",
description: "Write article on how to use Django with React",
completed: false,
},
];
class App extends Component {
constructor(props) {
super(props);
this.state = {
viewCompleted: false,
todoList: todoItems,
modal: false,
activeItem: {
title: "",
description: "",
completed: false,
},
};
}
toggle = () => {
this.setState({ modal: !this.state.modal });
};
handleSubmit = (item) => {
this.toggle();
alert("save" + JSON.stringify(item));
};
handleDelete = (item) => {
alert("delete" + JSON.stringify(item));
};
createItem = () => {
const item = { title: "", description: "", completed: false };
this.setState({ activeItem: item, modal: !this.state.modal });
};
editItem = (item) => {
this.setState({ activeItem: item, modal: !this.state.modal });
};
displayCompleted = (status) => {
if (status) {
return this.setState({ viewCompleted: true });
}
return this.setState({ viewCompleted: false });
};
renderTabList = () => {
return (
<div className="nav nav-tabs">
<span
className={this.state.viewCompleted ? "nav-link active" : "nav-link"}
onClick={() => this.displayCompleted(true)}
>
Complete
</span>
<span
className={this.state.viewCompleted ? "nav-link" : "nav-link active"}
onClick={() => this.displayCompleted(false)}
>
Incomplete
</span>
</div>
);
};
renderItems = () => {
const { viewCompleted } = this.state;
const newItems = this.state.todoList.filter(
(item) => item.completed === viewCompleted
);
return newItems.map((item) => (
<li
key={item.id}
className="list-group-item d-flex justify-content-between align-items-center"
>
<span
className={`todo-title mr-2 ${
this.state.viewCompleted ? "completed-todo" : ""
}`}
title={item.description}
>
{item.title}
</span>
<span>
<button
className="btn btn-secondary mr-2"
onClick={() => this.editItem(item)}
>
Edit
</button>
<button
className="btn btn-danger"
onClick={() => this.handleDelete(item)}
>
Delete
</button>
</span>
</li>
));
};
render() {
return (
<main className="container">
<h1 className="text-white text-uppercase text-center my-4">Todo app</h1>
<div className="row">
<div className="col-md-6 col-sm-10 mx-auto p-0">
<div className="card p-3">
<div className="mb-4">
<button
className="btn btn-primary"
onClick={this.createItem}
>
Add task
</button>
</div>
{this.renderTabList()}
<ul className="list-group list-group-flush border-top-0">
{this.renderItems()}
</ul>
</div>
</div>
</div>
{this.state.modal ? (
<Modal
activeItem={this.state.activeItem}
toggle={this.toggle}
onSave={this.handleSubmit}
/>
) : null}
</main>
);
}
}
export default App;
変更を保存し、Webブラウザでアプリケーションを確認します。
編集して保存しようとした場合 Todo
アイテム、あなたはを表示するアラートを受け取ります Todo
アイテムのオブジェクト。 保存または削除をクリックすると、 Todo
アイテム。
注::ReactおよびReactstrapのバージョンによっては、コンソールエラーが発生する場合があります。 改訂時、 Warning: Legacy context API has been detected within a strict-mode tree.
と Warning: findDOMNode is deprecated in StrictMode.
既知問題です。
次に、前のセクションで作成したDjangoAPIと相互作用するようにアプリケーションを変更します。 最初のターミナルウィンドウに戻り、サーバーが実行されていることを確認します。 実行されていない場合は、次のコマンドを使用します。
- python manage.py runserver
注:このターミナルウィンドウを閉じた場合は、に移動する必要があることに注意してください。 backend
ディレクトリを作成し、仮想Pipenvシェルを使用します。
バックエンドサーバー上のAPIエンドポイントにリクエストを送信するには、次のJavaScriptライブラリをインストールします。 axios
.
2番目のターミナルウィンドウで、 frontend
ディレクトリとインストール axios
:
- npm install axios@0.21.1
次に、 frontend/package.json
コードエディタでファイルを作成し、 proxy
:
[...]
"name": "frontend",
"version": "0.1.0",
"private": true,
"proxy": "http://localhost:8000",
"dependencies": {
"axios": "^0.18.0",
"bootstrap": "^4.1.3",
"react": "^16.5.2",
"react-dom": "^16.5.2",
"react-scripts": "2.0.5",
"reactstrap": "^6.5.0"
},
[...]
プロキシは、APIリクエストをトンネリングするのに役立ちます http://localhost:8000
Djangoアプリケーションがそれらを処理する場所。 これなしで proxy
、フルパスを指定する必要があります。
axios.get("http://localhost:8000/api/todos/")
と proxy
、相対パスを指定できます。
axios.get("/api/todos/")
注:プロキシをアプリケーションに登録するには、開発サーバーを再起動する必要がある場合があります。
再訪 frontend/src/App.js
ファイルを作成し、コードエディタで開きます。 このステップでは、ハードコードされたものを削除します todoItems
バックエンドサーバーへのリクエストからのデータを使用します。 handleSubmit
と handleDelete
を開きます App.js
ファイルを作成し、次の最終バージョンに置き換えます。
import React, { Component } from "react";
import Modal from "./components/Modal";
import axios from "axios";
class App extends Component {
constructor(props) {
super(props);
this.state = {
viewCompleted: false,
todoList: [],
modal: false,
activeItem: {
title: "",
description: "",
completed: false,
},
};
}
componentDidMount() {
this.refreshList();
}
refreshList = () => {
axios
.get("/api/todos/")
.then((res) => this.setState({ todoList: res.data }))
.catch((err) => console.log(err));
};
toggle = () => {
this.setState({ modal: !this.state.modal });
};
handleSubmit = (item) => {
this.toggle();
if (item.id) {
axios
.put(`/api/todos/${item.id}/`, item)
.then((res) => this.refreshList());
return;
}
axios
.post("/api/todos/", item)
.then((res) => this.refreshList());
};
handleDelete = (item) => {
axios
.delete(`/api/todos/${item.id}/`)
.then((res) => this.refreshList());
};
createItem = () => {
const item = { title: "", description: "", completed: false };
this.setState({ activeItem: item, modal: !this.state.modal });
};
editItem = (item) => {
this.setState({ activeItem: item, modal: !this.state.modal });
};
displayCompleted = (status) => {
if (status) {
return this.setState({ viewCompleted: true });
}
return this.setState({ viewCompleted: false });
};
renderTabList = () => {
return (
<div className="nav nav-tabs">
<span
onClick={() => this.displayCompleted(true)}
className={this.state.viewCompleted ? "nav-link active" : "nav-link"}
>
Complete
</span>
<span
onClick={() => this.displayCompleted(false)}
className={this.state.viewCompleted ? "nav-link" : "nav-link active"}
>
Incomplete
</span>
</div>
);
};
renderItems = () => {
const { viewCompleted } = this.state;
const newItems = this.state.todoList.filter(
(item) => item.completed === viewCompleted
);
return newItems.map((item) => (
<li
key={item.id}
className="list-group-item d-flex justify-content-between align-items-center"
>
<span
className={`todo-title mr-2 ${
this.state.viewCompleted ? "completed-todo" : ""
}`}
title={item.description}
>
{item.title}
</span>
<span>
<button
className="btn btn-secondary mr-2"
onClick={() => this.editItem(item)}
>
Edit
</button>
<button
className="btn btn-danger"
onClick={() => this.handleDelete(item)}
>
Delete
</button>
</span>
</li>
));
};
render() {
return (
<main className="container">
<h1 className="text-white text-uppercase text-center my-4">Todo app</h1>
<div className="row">
<div className="col-md-6 col-sm-10 mx-auto p-0">
<div className="card p-3">
<div className="mb-4">
<button
className="btn btn-primary"
onClick={this.createItem}
>
Add task
</button>
</div>
{this.renderTabList()}
<ul className="list-group list-group-flush border-top-0">
{this.renderItems()}
</ul>
</div>
</div>
</div>
{this.state.modal ? (
<Modal
activeItem={this.state.activeItem}
toggle={this.toggle}
onSave={this.handleSubmit}
/>
) : null}
</main>
);
}
}
export default App;
The refreshList()
APIリクエストが完了するたびに呼び出される関数は再利用可能です。 Todoリストを更新して、追加されたアイテムの最新のリストを表示します。
The handleSubmit()
関数は、作成操作と更新操作の両方を処理します。 パラメータとして渡されたアイテムに id
、それからそれはおそらく作成されていないので、関数はそれを作成します。
この時点で、バックエンドサーバーが最初のターミナルウィンドウで実行されていることを確認します。
- python manage.py runserver
注:このターミナルウィンドウを閉じた場合は、に移動する必要があることに注意してください。 backend
ディレクトリを作成し、仮想Pipenvシェルを使用します。
そして、2番目のターミナルウィンドウで、 frontend
ディレクトリを作成し、フロントエンドアプリケーションを起動します。
- npm start
今あなたが訪問するとき http://localhost:3000
あなたのウェブブラウザで、あなたのアプリケーションはあなたがすることを可能にします READ
, CREATE
, UPDATE
、 と DELETE
タスク。
これで、Todoアプリケーションのフロントエンドとバックエンドが完成しました。
結論
この記事では、DjangoとReactを使用してTo-Doアプリケーションを構築しました。 あなたはこれを djangorestframework
, django-cors-headers
, axios
, bootstrap
、 と reactstrap
ライブラリ。
Djangoについて詳しく知りたい場合は、Djangoトピックページで演習とプログラミングプロジェクトを確認してください。
Reactの詳細については、 React.js シリーズのコーディング方法をご覧になるか、Reactトピックページで演習やプログラミングプロジェクトを確認してください。