Integrando Django con Reactjs usando Django REST Framework

En este artículo, aprenderemos el proceso de comunicación entre Django Backend y React js frontend utilizando Django REST Framework. En aras de una mejor comprensión del concepto, crearemos un Administrador de tareas simple y revisaremos los conceptos principales para este tipo de integración entre React js y Django.

Integrating-Django-with-Reactjs-using-Django-REST-Framework

Reactjs en pocas palabras es una biblioteca de Javascript para desarrollar aplicaciones de una sola página (SPA) con documentación muy detallada y bien estructurada . Para este proyecto, React servirá como interfaz, manejando la interfaz de usuario (UI) a través de la solicitud al backend de Django.

Descripción del proyecto:

Echemos un vistazo primero a lo que vamos a construir. Las siguientes imágenes muestran la interfaz de usuario del Administrador de tareas.

Esta aplicación de administrador de tareas es una especie de lista de tareas pendientes. Aquí tendremos tres botones como “Completado”, “Incompleto” y un botón para agregar la tarea llamado “Agregar tarea” como se muestra en la imagen de arriba.

Para agregar una tarea, haga clic en el botón Agregar tarea que abrirá una ventana dentro de la aplicación para agregar la tarea como se muestra a continuación. Aquí podemos agregar el «Título» para la tarea y darle una descripción dentro de la sección «Descripción». Finalmente, puede marcar o desmarcar dependiendo del estado de la tarea (es decir, Completada o Incompleta) como se muestra en la siguiente imagen:

Después de «Guardar» la tarea, puede navegar entre las pestañas Completado e Incompleto para realizar un seguimiento de las tareas como se muestra a continuación:

Aquí también tendrá la opción de «Eliminar» o «Editar» y la tarea existente como se muestra a continuación:

Todas las operaciones realizadas anteriormente son administradas por Django REST Framework.

Configuración del proyecto:

requisitos previos:

Entonces, los siguientes son los requisitos previos para el proyecto:

Para verificar si tiene Python 3 instalado, use el siguiente comando en su símbolo del sistema (ya que este proyecto está desarrollado en una máquina con Windows, usaremos el símbolo del sistema, pero dependiendo de su sistema operativo, puede usar la terminal):

python -V

Esto mostrará la versión actual de Python en su sistema como se muestra a continuación:

Para verificar si el módulo Node está instalado, use el siguiente comando:

node --version

Esto le mostrará la versión del Node en su sistema como se muestra a continuación:

En este punto, estamos listos para comenzar ya que tenemos Python y Node js instalados en nuestro sistema.

Implementación:

Comencemos con el Backend.

Servidor (Django):

Ahora abramos nuestro símbolo del sistema. Ahora siga los pasos a continuación en el mismo orden para seguir este artículo.

Paso 1: Cree un directorio llamado «Django-react-app» usando el siguiente comando (el comando puede cambiar ligeramente dependiendo de su sistema operativo):

mkdir django-react-app

Paso 2: Movido al directorio que acabamos de crear usando el siguiente comando:

cd django-react-project

Paso 3: ahora crea un entorno virtual usando el siguiente comando:

python -m venv dar

Hemos llamado a nuestro entorno virtual «dar» , abreviatura de Django y reaccionar. Esto es necesario ya que no tenemos que instalar paquetes y dependencias globalmente. También es una buena práctica de programación.

Paso 4: active el entorno virtual que acabamos de crear usando el siguiente comando:

dar\Scripts\activate.bat

Esto activará nuestra máquina virtual como se muestra a continuación:

Paso 5: ahora instale Django dentro de la máquina virtual usando el siguiente comando:

pip install django

Recibirá un mensaje similar a medida que se complete la instalación:

Paso 6: Ahora vamos a crear nuestro proyecto llamado » backend» para nuestro backend de Django. Para hacerlo, use el siguiente comando:

django-admin startproject backend

La aplicación Django-react será nuestra carpeta principal y dentro de ella tendremos dos carpetas, una para el backend y otra para el frontend que crearemos más adelante.

Paso 7: Ahora navegue a la carpeta back-end usando el siguiente comando:

cd backend

Paso 8: Ahora iniciaremos nuestra aplicación y la llamaremos «todo» usando el siguiente comando:

python manage.py startapp todo

La aplicación se crea usando el comando anterior como se muestra a continuación:

Ahora avancemos e iniciemos el código VS y abramos la carpeta del proyecto dentro de él. En esta etapa, la estructura de nuestro proyecto se verá a continuación:

 Paso 9: ahora use el siguiente comando para migrar el proyecto:

python manage.py migrate

Las migraciones se aplicarán como se muestra a continuación:

Paso 10: Ahora ejecutemos el servidor usando el siguiente comando:

python manage.py runserver

Ahora puede visitar el host local para comprobar si el proyecto se ha iniciado correctamente. Como puede ver en la siguiente imagen, el proyecto está en marcha:

Paso 11: ahora debemos realizar algunos pasos de configuración dentro del archivo settings.py . En la sección INSTALLED_APPS agregue el nombre de la aplicación que creamos (es decir, todo) como se muestra a continuación:

Python3

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

En este punto, el archivo settings.py se vería como a continuación:

Python3

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'

Paso 12: A continuación, necesitaremos crear un Modelo. El modelo determinará cómo se almacenan los elementos pendientes en la base de datos. Tendremos tres propiedades en el modelo:

  • Título: Este será el título de la tarea con una extensión máxima de 150 caracteres.
  • Descripción: Esta será la descripción de la tarea con una extensión máxima de 500 caracteres.
  • Completado: Este será un valor booleano, que se utilizará para determinar el estado actual de la tarea. De forma predeterminada, se establecerá en falso.

Así que adelante, abra el archivo models.py y el siguiente código:

Python3

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

También crearemos una representación de string del título dentro de la clase Todo de la siguiente manera:

Python3

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

En este punto, nuestro archivo models.py se verá así:

Python3

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

Paso 13: Ahora sigamos adelante y hagamos migraciones. Tenga en cuenta que cada vez que realice cambios en el archivo models.py , necesitaremos realizar migraciones. Use el siguiente comando para hacerlo:

python manage.py makemigrations

El siguiente mensaje se generará cuando su migración esté lista:

Paso 14: Ahora apliquemos todas las migraciones usando el siguiente comando:

python manage.py migrate

Esto aplicará nuestras migraciones como se muestra a continuación:

Ahora podemos probar para ver que las operaciones CRUD funcionan en el archivo del modelo de tareas pendientes usando el sitio de administración (o la interfaz). Para ello, necesitaremos registrar los modelos en el archivo admin.py .

Paso 15: Abra el archivo admin.py y agregue el siguiente código:

Python3

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)

Paso 16: Ahora vamos a crear un superusuario usando el siguiente comando:

python manage.py createsuperuser

Aquí usaremos las siguientes credenciales:

  • Nombre de usuario: frikis
  • Dirección de correo electrónico: geeks@geeksforgeeks.org
  • Contraseña: 12345

Nota: Puede configurar sus credenciales según sus necesidades. Las credenciales anteriores no necesitan ser las mismas. 

Recibiríamos el siguiente mensaje cuando se crea el superusuario:

Paso 17: ahora ejecutemos el servidor y verifiquemos que todo va según lo previsto hasta ahora usando el siguiente comando:

python manage.py runserver

Navega al siguiente enlace:

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

Esto nos mostrará la página de administración como se muestra a continuación:

Aquí complete sus credenciales e inicie sesión. Usaremos las credenciales que usamos al crear el superusuario:

Esto nos llevará a la siguiente página. Aquí podemos ver nuestros usuarios, la aplicación y los grupos como se muestra a continuación:

Usuarios:

Que hacer:

Vamos a agregarle alguna tarea y guardarla como se muestra a continuación:

Podemos ver esta tarea listada en la sección de tareas como se muestra a continuación:

Creando la API:

Para crear la API necesitaremos instalar Django REST Framework for Serializers. También necesitamos Django-cors-headers para incluir en la lista blanca el puerto 3000, que es el puerto predeterminado para React.

Ahora siga los pasos a continuación para crear el marco Django REST:

Paso 1:   Para instalar el marco Django REST, use el siguiente comando en el directorio backend:

pip install djangorestframework

El siguiente mensaje se mostrará una vez que se complete la instalación:

Paso 2: ahora instale D jango-cors-headers usando el siguiente comando:

pip install django-cors-headers

El siguiente mensaje se mostrará una vez que se complete la instalación:

Paso 3: ahora abra el archivo setting.py y agregue las dependencias que acabamos de instalar a INSTALLED_APPS como se muestra a continuación:

Python3

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

Paso 4: También en el archivo settings.py necesitamos incluir en la lista blanca el puerto localhost 3000. Si no lo hacemos, habrá un bloqueo entre localhost:8000 y localhost:3000. Agregue el siguiente código para lograr lo mismo:

Python3

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

Paso 5: en la sección MIDDLEWARE, debemos agregar la configuración cors-headers como se muestra a continuación:

Python3

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

En este punto, nuestro archivo settings.py se vería así:

Python3

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'

Ahora necesitamos crear los serializadores para el modelo de datos Todo. Los serializadores son responsables de convertir las instancias del modelo a JSON. Esto ayudará a la interfaz a trabajar fácilmente con los datos recibidos. JSON es el estándar para el intercambio de datos en la web.

Paso 6: Ahora cree un archivo dentro de la carpeta de tareas pendientes y asígnele el nombre serializers.py. Dentro de la carpeta agrega el siguiente código:

Python3

# 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')

Paso 7: Ahora es el momento de crear las Vistas. Así que abre el archivo views.py . Ahora agregue el siguiente código al archivo:

Python3

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

Paso 8: Ahora abra el archivo urls.py y agregue el siguiente código.

Python3

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

Este es el paso final para crear la API REST y ahora podemos realizar todas las operaciones CRUD. Los routers nos permiten realizar consultas. Por ejemplo, si vamos a “tareas”, esto devolverá la lista de todas las tareas. Además, puede tener una sola ‘tarea’ con una identificación para devolver una sola tarea, donde la identificación es la clave principal.

Ahora vamos a comprobar si estamos avanzando en la dirección correcta. Así que ejecuta el servidor y navega a la siguiente URL:

localhost:8000/api

Si todo va bien, obtendremos el siguiente resultado:

Como puede ver, nuestra API está en funcionamiento.

Ahora bien, si navegamos a los siguientes enlaces, podemos ver e interactuar con nuestras tareas:

locaLHOST:8000/api/tasks

Interfaz (Reaccionar js):

Ahora construyamos la interfaz para nuestra aplicación Todo. Para esto, siga los siguientes pasos:

Paso 1: navegue al directorio principal del proyecto (es decir, Django-react-app) y active el entorno virtual usando el siguiente comando:

dar\Scripts\activate.bat

Paso 2: ahora use el siguiente comando para crear un modelo de la aplicación React js:

npx create-react-app frontend

Aquí, npx significa paquete ejecutable de Node. Después de configurar el repetitivo, recibirá el siguiente mensaje:

También necesitaremos algo de estilo de interfaz de usuario para el diseño de la interfaz de usuario, específicamente reactstrap y bootstrap.

Paso 3: Entonces, use el siguiente comando para instalar reactstrap y bootstrap en el proyecto:

npm install reactstrap bootstrap

Paso 4: Primero muévase a la carpeta Frontend y use el siguiente comando para ejecutar el servidor React para asegurarse de que todo funcione hasta este punto:

npm start

Si todo está bien, obtendrá la siguiente página en localhost: 3000

Paso 5: Ahora abre el archivo App.js en la carpeta frontend. Y borre el código repetitivo y cámbielo al siguiente código:

Javascript

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

En este punto, la interfaz se verá como se muestra a continuación:

Como se puede ver en la imagen de arriba. Cualquier cambio realizado en el archivo App.js se refleja directamente en la interfaz de usuario.

Paso 6: ahora el código del archivo App.js. Se agregan comentarios al código para una mejor comprensión.

Javascript

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

Paso 7: ahora abra el archivo Index.css , borre el CSS que contiene y agregue el siguiente CSS en el archivo:

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

Paso 8: Ahora cree una nueva carpeta llamada «Componentes» en el directorio src y agregue un archivo Modal.js. Luego agregue el siguiente código.

Javascript

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

Paso 10: realice los cambios en el archivo index.js de la siguiente manera:

Javascript

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")
);

Conexión API:

Para que podamos realizar requests a los puntos finales de la API en el servidor backend de Django, necesitaremos instalar Axios. Use el siguiente comando dentro de la carpeta frontend para instalar Axios:

npm install axios

Producción:

Enhorabuena!!. En este punto, ha creado con éxito una aplicación Fullstack Django-React y ha utilizado el marco Django REST para establecer la comunicación entre el frontend y el backend.

Publicación traducida automáticamente

Artículo escrito por ddeevviissaavviittaa y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *