====== Integració de Django amb Reactjs ======
De manera simplificada, //Reactjs// és una biblioteca Javascript per desenvolupar aplicacions de pàgina única (SPA), amb una documentació molt detallada i ben estructurada. Per a aquest exemple, on gestionarem clients i els seus comptes associats, React servirà com a frontend, gestionant la interfície d'usuari (UI) a través de la petició al framework de Django i amb l'ajuda de Django REST Framework.
Referències:
* Web oficial de Reactjs: https://react.dev/
* Web oficial de Django Framework: https://www.djangoproject.com
* Tutorial [[https://docs.djangoproject.com/en/stable/intro/tutorial01/|tutorial de la web oficial]].
{{tag> #FpInfor #Daw #DawMp06 #DawMp07 django framework python react javascript web}}
===== Creació del projecte =====
Els passos a seguir per crear el projecte a Django són els següents (si tens dubtes o vols repassar el procés, et recomano que revisis el [[django|tutorial]]):
1. Crea el projecte "project" a **l'entorn virtual**. Recorda instal·lar Django dins l'entorn virtual activat
2. Crea l'aplicació "customers".
3. Configura el projecte (urls, localització) i verifica que s'accedeix correctament des del navegador.
4. Crea el model de dades (dins del fitxer //models.py// de l'aplicació customers). En aquest cas, treballarem amb les dues classes següents:
* **Customer**: customer_id (IntegerField) i customer_name (CharField(200))
* **Account**: account_id (IntegerField),customer (ForeignKey Customer) description (CharField(200)), limit(IntegerField)
--> Proposta d'implementació Customer i Account#
class Project(models.Model):
class Customer(models.Model):
customer_id = models.IntegerField(default=0)
customer_name = models.CharField(max_length=200)
def __str__(self):
return self.customer_name
class Account(models.Model):
account_id = models.IntegerField(default=0)
customer = models.ForeignKey(Customer, on_delete=models.CASCADE)
description = models.CharField(max_length=200)
limit = models.IntegerField(default=0)
def __str__(self):
return self.description
<--
Aquest model no contempla que les claus primàries siguin autonumèriques ni la cardinalitat de la interrelació (//1 client pot tenir N comptes, però 1 compte només pot estar associat a 1 client//). Com ho faries?
Recorda que estem treballant a SQlite. Quins passos caldria fer per treballar contra una base de dades MySQL?
5. Registra el model de dades (a //admin.py//), afegeix l'aplicació (a //settings.py//) i migra el model per poder realitzar les operacions CRUD.
6. Crea el superadmin, comprova que pots accedir correctament al site d'administració i executa instruccions CRUD per validar el model. Hauries de veure una pantalla similar a aquesta:
{{ ::admin_django.jpg |}}
===== Integració de Reactjs (Creació de l'API) =====
**Important!** Verifica que tens instal·lat //node.js// a la teva màquina i, en cas contrari, instal·la la darrera versió.
1. Instal·la node.js al teu entorn virtual:
(env) $ apt install nodejs
\\
2. Instal·la Django REST Framework
(env) $ pip install djangorestframework
\\
3. Instal·la Django-cors-headers
(env) $ pip install django-cors-headers
\\
4. Obre el fitxer //setting.py// i afegeix les dues dependències que s'acaben d'instal·lar a //INSTALL_APPS// com es mostra a continuació:
INSTALLED_APPS = [
'customers.apps.CustomersConfig',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'corsheaders',
'rest_framework',
]
També cal que el port localhost 3000 estigui en la llista blanca al fitxer //settings.py//. Si no ho fem, hi haurà un bloc entre el localhost:8000 i el localhost:3000. Afegeix el codi següent per a aconseguir el mateix:
# White listing the localhost:3000 port
# for React
CORS_ORIGIN_WHITELIST = (
'http://localhost:3000',
)
5. A la secció MIDDLEWARE cal afegir la configuració de les capçaleres dels cors, tal com es mostra a continuació:
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'
]
És important que vagis revisant el terminal, per veure que en cada modificació del fitxer //settings.py// no dóna error l'aplicació.
6. Ara hem de crear els Serializers per al model de dades de Customers. Els Serializers són responsables de convertir instàncies de model a JSON. Això ajudarà el frontend a treballar amb les dades rebudes fàcilment. El JSON és l'estàndard per a l'intercanvi de dades al web.
Crea un fitxer dins de la carpeta "customers" i anomena'l //serializers.py//. Dins de la carpeta afegeix el codi següent:
# import serializers from the REST framework
from rest_framework import serializers
# import the Customer data model
from .models import Customer
# create a serializer class
class CustomerSerializer(serializers.ModelSerializer):
# create a meta class
class Meta:
model = Customer
fields = ('customer_id', 'customer_name')
7. Ara és el moment de crear les vistes. Per tant, obre el fitxer //views.py// i afegeix el codi següent al fitxer:
# import view sets from the REST framework
from rest_framework import viewsets
# import the CustomerSerializer from the serializer file
from .serializers import CustomerSerializer
# import the Customer model from the models file
from .models import Customer
# create a class for the Customer model viewsets
class CustomerView(viewsets.ModelViewSet):
# create a serializer class and
# assign it to the CustomerSerializerclass
serializer_class = CustomerSerializer
# define a variable and populate it
# with the Customer list objects
queryset = Customer.objects.all()
8. Obriu el fitxer urls.py i afegeix el codi següent:
from django.urls import include,path
from customers 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'customers',views.CustomerView, 'customers')
urlpatterns = [
path("", views.index),
path("customers/", include("customers.urls")),
path("admin/", admin.site.urls),
path('api/', include(router.urls))
]
Aquest és el pas final per a crear l'API REST. Ara podem realitzar totes les operacions CRUD. Els encaminadors ens permeten fer consultes. Per exemple, si anem a les "customers", això retornarà la llista de els clients.
Ara comprovem si estem avançant en la direcció correcta. Per tant, executeu el servidor i navegueu fins a l'URL següent:
localhost:8000/api
Si tot va bé, obtindrem el següent resultat:
{{ ::api.jpg |}}
Com podeu veure, la nostra API està en marxa. Ara, si provem d'accedir als "customers", podrem veure i interactuar amb les nostres tasques:
localhost:8000/api/customers
{{ ::api_customers_options.jpg |}}
Fins i tot, podem canviar el format dels resultats (per exemple, retornar en formar JSON):
{{ ::api_customers_json.jpg |}}
===== Integració de Reactjs (FrontEnd) =====
1. Crea una "boilerplate" de l'aplicació Js React:
npx create-react-app frontend
on npx significa //Node Package Executable//
Només funcionarà la sentència anterior amb versions de node.js superiors a la 14.0, així que si et dóna error, caldrà que l'actualitzis. Pots seguir aquest [[https://www.cyberithub.com/how-to-install-the-latest-version-of-node-js-on-ubuntu-debian/|tutorial]]. Tingues paciència, perquè aquest pas trigarà força!
2. Instal·la reactstrap i bootstrap al projecte (per donar una mica d'estil al disseny de la interfície d'usuari):
npm install reactstrap bootstrap
3. Des de la terminal, accedeix al directori de frontend i executa la següent instrucció, per tal de verificar que tot funciona correctament:
npm start
Si és així, et sortirà una pantalla similar a aquesta (en l'adreça localhost:3000):
{{ ::react_app.png |}}
4. Obre el fitxer //App.js// a la carpeta del frontend. Elimina el codi existent i substitueix-lo pel codi següent:
import "./App.css";
function App() {
return
Gestió de clients
;
}
export default App;
5. El pas anterior era un exemple per validar l'aplicació. Substitueix-lo, en el fitxer //App.js//, pel codi següent:
// import Component from the react module
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,
activeItem: {
title: "",
description: "",
completed: false
},
customersList: []
};
}
componentDidMount() {
this.refreshList();
}
refreshList = () => {
axios //Axios to send and receive HTTP requests
.get("http://localhost:8000/api/customers/")
.then(res => this.setState({ customersList: res.data }))
.catch(err => console.log(err));
};
displayCompleted = status => {
if (status) {
return this.setState({ viewCompleted: true });
}
return this.setState({ viewCompleted: false });
};
renderTabList = () => {
return (
{this.state.modal ? (
) : null}
);
}
}
export default App;
6. Obre el fitxer //Index.css//, neteja el CSS que hi ha a dins i afegeix el següent codi al fitxer:
.customer-title {
cursor: pointer;
}
.completed-customer {
text-decoration: line-through;
}
.customer-list > span {
padding: 5px 8px;
border: 1px solid rgb(7, 167, 68);
border-radius: 10px;
margin-right: 5px;
cursor: pointer;
}
.customer-list > span.active {
background-color: rgb(6, 139, 12);
color: #fff;
}
7. Crea una carpeta nova anomenada "Components" al directori //src// i afegeix un fitxer //Modal.js//. Després, afegeix el codi següent:
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";
class CustomModal extends Component {
constructor(props) {
super(props);
this.state = {
activeItem: this.props.activeItem
};
}
// changes handler to check if a checkbox is checked 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 (
Customer Item
{/* create a modal footer */}
);
}
}
export default CustomModal
8. Fes els canvis indicats a continuació al fitxer //index.js//:
import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import "bootstrap/dist/css/bootstrap.min.css";
ReactDOM.render(
,
document.getElementById("root")
);
9. Per fer les peticions als endpoints de l'API al servidor del framework de Django, necessitarem instal·lar l'Axios. Utilitza l'ordre següent dins de la carpeta del framework per a instal·lar l'Axios:
npm install axios
I, amb aquest pas, ja tenim una aplicació Fullstack Django-React utilitzant el framework REST Django per establir la comunicació entre el frontend i el backend.
**Exercici:**
Aplica la serialització de manera que es puguin gestionar els comptes associats als clients.
\\