使用Django REST框架将Django与Reactjs整合起来

使用Django REST框架将Django与Reactjs整合起来

在这篇文章中,我们将学习使用Django REST框架在Django后端和React js前端之间进行通信的过程。为了更好地理解这个概念,我们将建立一个简单的任务管理器,并通过React js和Django之间这种类型的集成的主要概念。

使用Django REST框架将Django与Reactjs整合起来

Reactjs简而言之是一个用于开发单页应用程序(SPA)的Javascript库,具有非常详细和结构良好的文档。在这个项目中,React将作为前端,通过对Django后台的请求来处理用户界面(UI)。

项目概述

让我们先看看我们将建立什么。下面的图片显示了任务管理器的用户界面。

这个任务管理器应用程序是一种待办事项清单。这里我们有三个按钮,分别是 “已完成”、”未完成 “和一个名为 “添加任务 “的按钮来添加任务,如上图所示。

使用Django REST框架将Django与Reactjs整合起来

为了添加一个任务,你点击添加任务按钮,这将在应用程序中打开一个窗口来添加任务,如下图所示。在这里,我们可以为任务添加 “标题”,并在 “描述 “部分给它一个描述。最后,你可以根据任务的状态(即,已完成或未完成)进行检查或取消检查,如下图所示。

使用Django REST框架将Django与Reactjs整合起来

在你 “保存 “任务后,你可以在 “已完成 “和 “未完成 “选项卡之间浏览,以跟踪任务,如下所示。

使用Django REST框架将Django与Reactjs整合起来

在这里,你也可以选择 “删除 “或 “编辑 “现有任务,如下图所示。

使用Django REST框架将Django与Reactjs整合起来

以上执行的所有操作都由Django REST框架管理。

创建项目:

先决条件:

因此,以下是项目的先决条件。

  • Python 3 (preferably Python 3.5 and above)
  • Node js
  • VS Code ( or, IDE of your choice)

为了验证你是否安装了Python 3,在你的命令提示符中使用以下命令(由于这个项目是在Windows机器上开发的,我们将使用命令提示符,但根据你的操作系统,你可以使用终端)。

python -V

这将显示出你系统上当前的Python版本,如下图所示。

使用Django REST框架将Django与Reactjs整合起来

要检查Node模块是否已经安装,请使用下面的命令。

node --version

这将显示你的系统上的节点版本,如下图所示。

使用Django REST框架将Django与Reactjs整合起来

在这一点上,我们就可以开始了,因为我们的系统中已经安装了Python和Node js。

实现:

让我们从后端开始。

后端(Django):

现在让我们打开我们的命令提示符。现在按照下面的步骤,以同样的顺序来跟读本文。

第1步:使用以下命令创建一个名为_“Django-react-app “的目录(该命令可能会根据你的操作系统而略有变化)。

mkdir django-react-app

第2步:移动到我们刚刚创建的目录中,使用下面的命令。

cd django-react-project

第3步:现在使用下面的命令创建一个虚拟环境。

python -m venv dar

我们将我们的虚拟环境命名为_”dar” _,是Django和react的缩写。这是必要的,因为我们不需要在全局范围内安装软件包和依赖关系。这也是一种良好的编程实践。

第4步:用下面的命令激活我们刚刚创建的虚拟环境。

dar\Scripts\activate.bat

这将激活我们的虚拟机,如下图所示。

使用Django REST框架将Django与Reactjs整合起来

步骤5:现在使用以下命令在虚拟机内安装Django。

pip install django

当你的安装完成后,你会得到一个类似的消息。

使用Django REST框架将Django与Reactjs整合起来

第6步:现在让我们为我们的Django后端创建名为”_backend “的项目。要做到这一点,请使用下面的命令。

django-admin startproject backend

Django-react应用程序将是我们的主文件夹,在它里面,我们将有两个文件夹,一个用于后台,一个用于我们稍后创建的前台。

第7步:现在使用以下命令导航到后台文件夹。

cd backend

第8步:现在我们将启动我们的应用程序,并使用下面的命令调用它 “todo”。

python manage.py startapp todo

使用上述命令可以创建应用程序,如下图所示。

使用Django REST框架将Django与Reactjs整合起来

现在让我们继续启动VS代码并打开里面的项目文件夹。在这个阶段,我们的项目结构将看起来像下面这样。

使用Django REST框架将Django与Reactjs整合起来

第9步:现在使用下面的命令来迁移该项目。

python manage.py migrate

迁移将被应用,如下图所示。

使用Django REST框架将Django与Reactjs整合起来

第10步:现在让我们使用下面的命令运行服务器。

python manage.py runserver

现在你可以访问本地主机,检查项目是否已经正常启动。正如你在下面的图片中看到的,项目已经启动并运行。

使用Django REST框架将Django与Reactjs整合起来

第11步:现在我们需要在_settings.py _文件中采取一些配置步骤。在INSTALLED_APPS部分添加我们创建的应用程序的名称(即,todo),如下图所示。

# Application definition
 
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'todo',
]

在这一点上,settings.py文件将看起来像下面这样。

from pathlib import Path
 
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
 
 
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/
 
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'django-insecure-_c3!4)8+yce2l-ju@gz@b6(e0$00y@xhx7+lxk1p==k+pyqko3'
 
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
 
ALLOWED_HOSTS = []
 
 
# Application definition
 
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    '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',
]
 
ROOT_URLCONF = 'backend.urls'
 
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]
 
WSGI_APPLICATION = 'backend.wsgi.application'
 
 
# Database
# https://docs.djangoproject.com/en/3.2/ref/settings/#databases
 
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'db.sqlite3',
    }
}
 
 
# Password validation
# https://docs.djangoproject.com/en/3.2/ref/settings/#auth-password-validators
 
AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]
 
 
# Internationalization
# https://docs.djangoproject.com/en/3.2/topics/i18n/
 
LANGUAGE_CODE = 'en-us'
 
TIME_ZONE = 'UTC'
 
USE_I18N = True
 
USE_L10N = True
 
USE_TZ = True
 
 
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.2/howto/static-files/
 
STATIC_URL = '/static/'
 
# Default primary key field type
# https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field
 
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'

第12步:接下来,我们将需要创建一个模型。模型将决定如何将待办事项__项目存储在数据库中。我们在模型中会有三个属性。

  • 标题。这将是任务的标题,最大长度为150个字符。
  • 描述。这将是任务的描述,最大长度为500个字符。
  • 已完成。这将是一个布尔值,它将被用来确定任务的当前状态。默认情况下,它将被设置为false。

因此,继续打开models.py文件和以下代码。

class Todo(models.Model):
    title=models.CharField(max_length=150)
    description=models.CharField(max_length=500)
    completed=models.BooleanField(default=False)

我们还将在Todo类里面创建一个字符串表示的标题,如下所示。

def __str__(self):
 
  #it will return the title
  return self.title G")

在这一点上,我们的models.py文件将看起来像这样。

from django.db import models
 
class Todo(models.Model):
    title=models.CharField(max_length=150)
    description=models.CharField(max_length=500)
    completed=models.BooleanField(default=False)
 
    # string representation of the class
    def __str__(self):
 
        #it will return the title
        return self.title

第13步:现在让我们继续做迁移。注意,每次你对models.py文件进行修改,我们都需要进行迁移。使用下面的命令来做。

python manage.py makemigrations

当你的迁移准备就绪时,将产生以下信息。

使用Django REST框架将Django与Reactjs整合起来

第14步:现在让我们使用下面的命令应用所有的迁移。

python manage.py migrate

这将应用我们的迁移,如下图所示。

使用Django REST框架将Django与Reactjs整合起来

现在我们可以测试一下CRUD操作是否在使用Admin站点(或者,界面)的todo模型文件上工作。为此,我们将需要在admin.py文件中注册这些模型。

第15步:打开_admin.py _文件,在其中添加以下代码。

from django.contrib import admin
 
# import the model Todo
from .models import Todo
 
# create a class for the admin-model integration
class TodoAdmin(admin.ModelAdmin):
 
    # add the fields of the model here
    list_display = ("title","description","completed")
 
# we will need to register the
# model class and the Admin model class
# using the register() method
# of admin.site class
admin.site.register(Todo,TodoAdmin)

第16步:现在让我们使用以下命令创建一个超级用户。

python manage.py createsuperuser

在这里,我们将使用以下凭证。

  • Username: Geeks
  • 电子邮件地址:geeks@geeksforgeeks.org
  • Password:12345

注意:你可以根据你的需要设置你的凭证。上述凭证不需要相同。

当超级用户被创建时,我们会得到以下信息。

使用Django REST框架将Django与Reactjs整合起来

第17步:现在让我们运行服务器,用下面的命令检查到目前为止一切都在按计划进行。

python manage.py runserver

导航到以下链接。

http://127.0.0.1:8000/admin/login/?next=/admin/

这将显示我们的管理页面,如下图所示。

使用Django REST框架将Django与Reactjs整合起来

在这里填写你的凭证并登录。我们将使用创建超级用户时使用的凭证。

使用Django REST框架将Django与Reactjs整合起来

这将引导我们进入以下页面。在这里,我们可以看到我们的用户、应用程序和组,如下图所示。

Users:

使用Django REST框架将Django与Reactjs整合起来

Todo:

使用Django REST框架将Django与Reactjs整合起来

让我们给它添加一些任务并保存,如下所示。

使用Django REST框架将Django与Reactjs整合起来

我们可以看到这项任务列在todo部分,如下图所示。

使用Django REST框架将Django与Reactjs整合起来

创建API

为了创建API,我们将需要安装Django REST Framework for Serializers。我们还需要Django-cors-headers来白名单3000端口,这是React的默认端口。

现在按照以下步骤来创建Django REST框架。

第1步:安装Django REST框架,在后台目录中使用以下命令。

pip install djangorestframework

安装完成后,将显示以下信息。

使用Django REST框架将Django与Reactjs整合起来

步骤2:现在使用以下命令安装D _jango-cors-headers _。

pip install django-cors-headers

安装完成后,将显示以下信息。

使用Django REST框架将Django与Reactjs整合起来

第3步:现在打开_setting.py _文件,将我们刚刚安装的两个依赖项添加到INSTALLED_APPS中,如下图所示。

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

第4步:在settings.py文件中,我们还需要把localhost的3000端口列入白名单。如果我们不这样做,在localhost:8000和localhost:3000之间会有一个块。添加下面的代码来实现同样的目的。

# White listing the localhost:3000 port
# for React
CORS_ORIGIN_WHITELIST = (
    'http://localhost:3000',
)

第5步:在MIDDLEWARE部分,我们需要添加cors-headers设置,如下图所示。

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'
]

在这一点上,我们的_settings.py _将看起来像下面这样。

from pathlib import Path
 
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
 
 
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/
 
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'django-insecure-_c3!4)8+yce2l-ju@gz@b6(e0$00y@xhx7+lxk1p==k+pyqko3'
 
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
 
ALLOWED_HOSTS = []
 
 
# Application definition
 
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'todo',
    'corsheaders',
    'rest_framework',
]
 
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'
]
 
ROOT_URLCONF = 'backend.urls'
 
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]
 
WSGI_APPLICATION = 'backend.wsgi.application'
 
 
# Database
# https://docs.djangoproject.com/en/3.2/ref/settings/#databases
 
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'db.sqlite3',
    }
}
 
 
# Password validation
# https://docs.djangoproject.com/en/3.2/ref/settings/#auth-password-validators
 
AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]
 
# White listing the localhost:3000 port
CORS_ORIGIN_WHITELIST = (
    'http://localhost:3000'
)
 
# Internationalization
# https://docs.djangoproject.com/en/3.2/topics/i18n/
 
LANGUAGE_CODE = 'en-us'
 
TIME_ZONE = 'UTC'
 
USE_I18N = True
 
USE_L10N = True
 
USE_TZ = True
 
 
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.2/howto/static-files/
 
STATIC_URL = '/static/'
 
# Default primary key field type
# https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field
 
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'

现在我们需要为Todo数据模型创建序列化器。序列器负责将模型实例转换为JSON。这将有助于前端轻松处理收到的数据。JSON是网络上数据交换的标准。

第6步:现在在todo文件夹内创建一个文件,命名为_serializers.py. _在该文件夹内添加以下代码。

# import serializers from the REST framework
from rest_framework import serializers
 
# import the todo data model
from .models import Todo
 
# create a serializer class
class TodoSerializer(serializers.ModelSerializer):
 
    # create a meta class
    class Meta:
        model = Todo
        fields = ('id', 'title','description','completed')

第7步:现在是创建视图的时候了。所以打开_views.py _文件。现在在该文件中添加以下代码。

from django.shortcuts import render
 
# import view sets from the REST framework
from rest_framework import viewsets
 
# import the TodoSerializer from the serializer file
from .serializers import TodoSerializer
 
# import the Todo model from the models file
from .models import Todo
 
# create a class for the Todo model viewsets
class TodoView(viewsets.ModelViewSet):
 
    # create a serializer class and
    # assign it to the TodoSerializer class
    serializer_class = TodoSerializer
 
    # define a variable and populate it
    # with the Todo list objects
    queryset = Todo.objects.all()

第8步:现在打开urls.py文件,在其中添加以下代码。

from django.contrib import admin
 
# add include to the path
from django.urls import path, include
 
# import views from todo
from todo import views
 
# import routers from the REST framework
# it is necessary for routing
from rest_framework import routers
 
# create a router object
router = routers.DefaultRouter()
 
# register the router
router.register(r'tasks',views.TodoView, 'task')
 
urlpatterns = [
    path('admin/', admin.site.urls),
 
    # add another path to the url patterns
    # when you visit the localhost:8000/api
    # you should be routed to the django Rest framework
    path('api/', include(router.urls))
 
 
]

这是创建REST API的最后一步,我们现在可以执行所有的CRUD操作。路由器允许我们进行查询。例如,如果我们去 “tasks”,这将返回所有任务的列表。此外,你可以有一个单一的 “task”,其中有一个_id _来返回一个单一的任务,其中id是主键。

现在让我们检查一下我们是否在正确的方向上前进。因此,运行服务器并导航到以下网址。

localhost:8000/api

如果一切顺利,我们将得到以下结果。

使用Django REST框架将Django与Reactjs整合起来

正如你所看到的,我们的API已经启动并运行。

现在,如果我们导航到以下链接,就可以查看并与我们的任务互动。

locaLHOST:8000/api/tasks

使用Django REST框架将Django与Reactjs整合起来

前端(React js):

现在让我们为我们的Todo应用程序建立前端。为此,请按照以下步骤进行。

第1步:导航到主项目目录(即Django-react-app),使用以下命令激活虚拟环境。

dar\Scripts\activate.bat

第2步:现在使用下面的命令来创建React js应用程序的模板。

npx create-react-app frontend

这里,npx代表Node Package Executable。在模板设置完成后,你会得到以下信息。

使用Django REST框架将Django与Reactjs整合起来

我们还需要一些UI设计方面的天赋,特别是reactstrap和bootstrap。

第3步:所以,使用下面的命令在项目中安装reactstrap和bootstrap。

npm install reactstrap bootstrap

第四步:首先进入Frontend文件夹,使用下面的命令运行React服务器,以确保到此为止一切正常。

npm start

如果一切正常,你会在localhost:3000上得到以下页面

使用Django REST框架将Django与Reactjs整合起来

第5步:现在打开前端文件夹中的App.js文件。并清除模板代码,将其改为以下代码。

import "./App.css";
 
function App() {
  return <div className="App"><h2>Welcome to Geeksforgeeks!</h2></div>;
}
 
export default App;

在这一点上,前台看起来会像下面这样。

使用Django REST框架将Django与Reactjs整合起来

正如你在上面的图片中所看到的。对App.js文件所做的任何修改都会直接反映到用户界面上。

第6步:现在将代码放到App.js文件。为了更好地理解,在代码中加入了注释。

// import Component from the react module
import React, { Component } from "react";
import Modal from "./components/Modal";
import axios from 'axios'; 
 
// create a class that extends the component
class App extends Component {
 
  // add a constructor to take props
  constructor(props) {
    super(props);
     
    // add the props here
    this.state = {
     
      // the viewCompleted prop represents the status
      // of the task. Set it to false by default
      viewCompleted: false,
      activeItem: {
        title: "",
        description: "",
        completed: false
      },
       
      // this list stores all the completed tasks
      taskList: []
    };
  }
 
  // Add componentDidMount()
  componentDidMount() {
    this.refreshList();
  }
 
  
  refreshList = () => {
    axios   //Axios to send and receive HTTP requests
      .get("http://localhost:8000/api/tasks/")
      .then(res => this.setState({ taskList: res.data }))
      .catch(err => console.log(err));
  };
 
  // this arrow function takes status as a parameter
  // and changes the status of viewCompleted to true
  // if the status is true, else changes it to false
  displayCompleted = status => {
    if (status) {
      return this.setState({ viewCompleted: true });
    }
    return this.setState({ viewCompleted: false });
  };
 
  // this array function renders two spans that help control
  // the set of items to be displayed(ie, completed or incomplete)
  renderTabList = () => {
    return (
      <div className="my-5 tab-list">
        <span
          onClick={() => this.displayCompleted(true)}
          className={this.state.viewCompleted ? "active" : ""}
        >
          completed
            </span>
        <span
          onClick={() => this.displayCompleted(false)}
          className={this.state.viewCompleted ? "" : "active"}
        >
          Incompleted
            </span>
      </div>
    );
  };
  // Main variable to render items on the screen
  renderItems = () => {
    const { viewCompleted } = this.state;
    const newItems = this.state.taskList.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
            onClick={() => this.editItem(item)}
            className="btn btn-secondary mr-2"
          >
            Edit
          </button>
          <button
            onClick={() => this.handleDelete(item)}
            className="btn btn-danger"
          >
            Delete
          </button>
        </span>
      </li>
    ));
  };
 
  toggle = () => {
    //add this after modal creation
    this.setState({ modal: !this.state.modal });
  };
  handleSubmit = (item) => {
    this.toggle();
    alert("save" + JSON.stringify(item));
  };
 
  // Submit an item
  handleSubmit = (item) => {
    this.toggle();
    if (item.id) {
      // if old post to edit and submit
      axios
        .put(`http://localhost:8000/api/tasks/{item.id}/`, item)
        .then((res) => this.refreshList());
      return;
    }
    // if new post to submit
    axios
      .post("http://localhost:8000/api/tasks/", item)
      .then((res) => this.refreshList());
  };
 
  // Delete item
  handleDelete = (item) => {
    axios
      .delete(`http://localhost:8000/api/tasks/${item.id}/`)
      .then((res) => this.refreshList());
  };
  handleDelete = (item) => {
    alert("delete" + JSON.stringify(item));
  };
 
  // Create item
  createItem = () => {
    const item = { title: "", description: "", completed: false };
    this.setState({ activeItem: item, modal: !this.state.modal });
  };
 
  //Edit item
  editItem = (item) => {
    this.setState({ activeItem: item, modal: !this.state.modal });
  };
 
  // Start by visual effects to viewer
  render() {
    return (
      <main className="content">
        <h1 className="text-success text-uppercase text-center my-4">
          GFG Task Manager
        </h1>
        <div className="row ">
          <div className="col-md-6 col-sm-10 mx-auto p-0">
            <div className="card p-3">
              <div className="">
                <button onClick={this.createItem} className="btn btn-info">
                  Add task
                </button>
              </div>
              {this.renderTabList()}
              <ul className="list-group list-group-flush">
                {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;

第7步:现在打开Index.css文件,清除里面的CSS,在文件中添加以下CSS。

.todo-title {
  cursor: pointer;
}
.completed-todo {
  text-decoration: line-through;
}
.tab-list > span {
  padding: 5px 8px;
  border: 1px solid rgb(7, 167, 68);
  border-radius: 10px;
  margin-right: 5px;
  cursor: pointer;
}
.tab-list > span.active {
  background-color: rgb(6, 139, 12);
  color: #fff;
}

第8步:现在在_src _目录下创建一个名为“Components “的新文件夹,并在其中添加一个文件Modal.js。然后在其中添加以下代码。

import React, { Component } from "react";
 
// importing all of these classes from reactstrap module
import {
  Button,
  Modal,
  ModalHeader,
  ModalBody,
  ModalFooter,
  Form,
  FormGroup,
  Input,
  Label
} from "reactstrap";
 
// build a class base component
class CustomModal extends Component {
  constructor(props) {
    super(props);
    this.state = {
      activeItem: this.props.activeItem
    };
  }
  // changes handler to check if a checkbox is checed or not
  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 });
  };
 
  // rendering modal in the custommodal class received toggle and on save as props,
  render() {
    const { toggle, onSave } = this.props;
    return (
      <Modal isOpen={true} toggle={toggle}>
        <ModalHeader toggle={toggle}> Task Item </ModalHeader>
        <ModalBody>
         
          <Form>
 
            {/* 3 formgroups
            1 title label */}
            <FormGroup>
              <Label for="title">Title</Label>
              <Input
                type="text"
                name="title"
                value={this.state.activeItem.title}
                onChange={this.handleChange}
                placeholder="Enter Task Title"
              />
            </FormGroup>
 
            {/* 2 description label */}
            <FormGroup>
              <Label for="description">Description</Label>
              <Input
                type="text"
                name="description"
                value={this.state.activeItem.description}
                onChange={this.handleChange}
                placeholder="Enter Task Description"
              />
            </FormGroup>
 
            {/* 3 completed label */}
            <FormGroup check>
              <Label for="completed">
                <Input
                  type="checkbox"
                  name="completed"
                  checked={this.state.activeItem.completed}
                  onChange={this.handleChange}
                />
                Completed
              </Label>
            </FormGroup>
          </Form>
        </ModalBody>
        {/* create a modal footer */}
        <ModalFooter>
          <Button color="success" onClick={() => onSave(this.state.activeItem)}>
            Save
          </Button>
        </ModalFooter>
      </Modal>
    );
  }
}
export default CustomModal

第10步:对_index.js _文件做如下修改。

import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
 
// importing css stylesheet to use the bootstrap class
// add this line only in this file
import "bootstrap/dist/css/bootstrap.min.css";
 
ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById("root")
);

API 连接:

为了让我们能够向Django后台服务器上的API端点发出请求,我们需要安装Axios。在frontend文件夹中使用以下命令来安装Axios。

npm install axios

输出:

使用Django REST框架将Django与Reactjs整合起来

祝贺你!!。在这一点上,你已经成功地建立了一个Fullstack Django-React应用程序,并使用Django REST框架来建立前端和后端的通信。

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程