Ací es mostren les diferències entre la revisió seleccionada i la versió actual de la pàgina.
Ambdós costats versió prèvia Revisió prèvia Següent revisió | Revisió prèvia | ||
integracio_de_django_amb_react [2023/07/06 08:59] raquel_alaman_navas |
integracio_de_django_amb_react [2023/07/06 10:25] (actual) raquel_alaman_navas [Integració de Reactjs (FrontEnd)] |
||
---|---|---|---|
Línia 24: | Línia 24: | ||
* **Account**: | * **Account**: | ||
- | --> Proposta implementació Customer i Account# | + | --> Proposta |
<file python models.py> | <file python models.py> | ||
Línia 125: | Línia 125: | ||
from rest_framework import serializers | from rest_framework import serializers | ||
- | # import the todo data model | + | # import the Customer |
from .models import Customer | from .models import Customer | ||
Línia 175: | Línia 175: | ||
# register the router | # register the router | ||
- | router.register(r' | + | router.register(r' |
urlpatterns = [ | urlpatterns = [ | ||
Línia 189: | Línia 189: | ||
Ara comprovem si estem avançant en la direcció correcta. Per tant, executeu el servidor i navegueu fins a l'URL següent: | Ara comprovem si estem avançant en la direcció correcta. Per tant, executeu el servidor i navegueu fins a l'URL següent: | ||
+ | < | ||
localhost: | localhost: | ||
+ | </ | ||
Si tot va bé, obtindrem el següent resultat: | Si tot va bé, obtindrem el següent resultat: | ||
+ | {{ ::api.jpg |}} | ||
+ | |||
+ | Com podeu veure, la nostra API està en marxa. Ara, si provem d' | ||
+ | < | ||
+ | localhost: | ||
+ | </ | ||
+ | {{ :: | ||
+ | |||
+ | Fins i tot, podem canviar el format dels resultats (per exemple, retornar en formar JSON): | ||
+ | {{ :: | ||
+ | |||
+ | ===== Integració de Reactjs (FrontEnd) ===== | ||
+ | |||
+ | 1. Crea una " | ||
+ | < | ||
+ | npx create-react-app frontend | ||
+ | </ | ||
+ | on npx significa //Node Package Executable// | ||
+ | |||
+ | <WRAP info> | ||
+ | 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' | ||
+ | </ | ||
+ | |||
+ | 2. Instal·la reactstrap i bootstrap al projecte (per donar una mica d' | ||
+ | < | ||
+ | npm install reactstrap bootstrap | ||
+ | </ | ||
+ | |||
+ | 3. Des de la terminal, accedeix al directori de frontend i executa la següent instrucció, | ||
+ | < | ||
+ | npm start | ||
+ | </ | ||
+ | |||
+ | Si és així, et sortirà una pantalla similar a aquesta (en l' | ||
+ | |||
+ | {{ :: | ||
+ | 4. Obre el fitxer //App.js// a la carpeta del frontend. Elimina el codi existent i substitueix-lo pel codi següent: | ||
+ | |||
+ | <file javascript App.js> | ||
+ | import " | ||
+ | |||
+ | function App() { | ||
+ | return <div className=" | ||
+ | } | ||
+ | |||
+ | export default App; | ||
+ | </ | ||
+ | |||
+ | 5. El pas anterior era un exemple per validar l' | ||
+ | <file javascript App.js> | ||
+ | // import Component from the react module | ||
+ | import React, { Component } from " | ||
+ | import Modal from " | ||
+ | import axios from ' | ||
+ | |||
+ | class App extends Component { | ||
+ | constructor(props) { | ||
+ | super(props); | ||
+ | |||
+ | this.state = { | ||
+ | |||
+ | viewCompleted: | ||
+ | activeItem: { | ||
+ | title: "", | ||
+ | description: | ||
+ | completed: false | ||
+ | }, | ||
+ | |||
+ | customersList: | ||
+ | }; | ||
+ | } | ||
+ | |||
+ | |||
+ | componentDidMount() { | ||
+ | this.refreshList(); | ||
+ | } | ||
+ | |||
+ | refreshList = () => { | ||
+ | axios // | ||
+ | .get(" | ||
+ | .then(res => this.setState({ customersList: | ||
+ | .catch(err => console.log(err)); | ||
+ | }; | ||
+ | |||
+ | displayCompleted = status => { | ||
+ | if (status) { | ||
+ | return this.setState({ viewCompleted: | ||
+ | } | ||
+ | return this.setState({ viewCompleted: | ||
+ | }; | ||
+ | |||
+ | |||
+ | renderTabList = () => { | ||
+ | return ( | ||
+ | <div className=" | ||
+ | <span | ||
+ | onClick={() => this.displayCompleted(true)} | ||
+ | className={this.state.viewCompleted ? " | ||
+ | > | ||
+ | completed | ||
+ | </ | ||
+ | <span | ||
+ | onClick={() => this.displayCompleted(false)} | ||
+ | className={this.state.viewCompleted ? "" | ||
+ | > | ||
+ | Incompleted | ||
+ | </ | ||
+ | </ | ||
+ | ); | ||
+ | }; | ||
+ | |||
+ | renderItems = () => { | ||
+ | const { viewCompleted } = this.state; | ||
+ | const newItems = this.state.taskList.filter( | ||
+ | (item) => item.completed === viewCompleted | ||
+ | ); | ||
+ | return newItems.map((item) => ( | ||
+ | <li | ||
+ | key={item.id} | ||
+ | className=" | ||
+ | > | ||
+ | <span | ||
+ | className={`customer-title mr-2 ${ | ||
+ | this.state.viewCompleted ? " | ||
+ | }`} | ||
+ | title={item.description} | ||
+ | > | ||
+ | {item.title} | ||
+ | </ | ||
+ | < | ||
+ | <button | ||
+ | onClick={() => this.editItem(item)} | ||
+ | className=" | ||
+ | > | ||
+ | Edit | ||
+ | </ | ||
+ | <button | ||
+ | onClick={() => this.handleDelete(item)} | ||
+ | className=" | ||
+ | > | ||
+ | Delete | ||
+ | </ | ||
+ | </ | ||
+ | </li> | ||
+ | )); | ||
+ | }; | ||
+ | |||
+ | toggle = () => { | ||
+ | //add this after modal creation | ||
+ | this.setState({ modal: !this.state.modal }); | ||
+ | }; | ||
+ | |||
+ | handleSubmit = (item) => { | ||
+ | this.toggle(); | ||
+ | | ||
+ | if (item.id) { | ||
+ | // if old post to edit and submit | ||
+ | axios | ||
+ | .put(`http:// | ||
+ | .then((res) => this.refreshList()); | ||
+ | return; | ||
+ | } | ||
+ | |||
+ | axios | ||
+ | .post(" | ||
+ | .then((res) => this.refreshList()); | ||
+ | }; | ||
+ | |||
+ | handleDelete = (item) => { | ||
+ | alert(" | ||
+ | axios | ||
+ | .delete(`http:// | ||
+ | .then((res) => this.refreshList()); | ||
+ | }; | ||
+ | | ||
+ | createItem = () => { | ||
+ | const item = { title: "", | ||
+ | this.setState({ activeItem: item, modal: !this.state.modal }); | ||
+ | }; | ||
+ | |||
+ | editItem = (item) => { | ||
+ | this.setState({ activeItem: item, modal: !this.state.modal }); | ||
+ | }; | ||
+ | |||
+ | render() { | ||
+ | return ( | ||
+ | <main className=" | ||
+ | <h1 className=" | ||
+ | GFG Task Manager | ||
+ | </h1> | ||
+ | <div className=" | ||
+ | <div className=" | ||
+ | <div className=" | ||
+ | <div className=""> | ||
+ | <button onClick={this.createItem} className=" | ||
+ | Add task | ||
+ | </ | ||
+ | </ | ||
+ | {this.renderTabList()} | ||
+ | <ul className=" | ||
+ | {this.renderItems()} | ||
+ | </ul> | ||
+ | </ | ||
+ | </ | ||
+ | </ | ||
+ | {this.state.modal ? ( | ||
+ | <Modal | ||
+ | activeItem={this.state.activeItem} | ||
+ | toggle={this.toggle} | ||
+ | onSave={this.handleSubmit} | ||
+ | /> | ||
+ | ) : null} | ||
+ | </ | ||
+ | ); | ||
+ | } | ||
+ | } | ||
+ | export default App; | ||
+ | </ | ||
+ | |||
+ | 6. Obre el fitxer // | ||
+ | |||
+ | <file css Index.css> | ||
+ | .customer-title { | ||
+ | cursor: pointer; | ||
+ | } | ||
+ | .completed-customer { | ||
+ | text-decoration: | ||
+ | } | ||
+ | .customer-list > span { | ||
+ | padding: 5px 8px; | ||
+ | border: 1px solid rgb(7, 167, 68); | ||
+ | border-radius: | ||
+ | margin-right: | ||
+ | cursor: pointer; | ||
+ | } | ||
+ | .customer-list > span.active { | ||
+ | background-color: | ||
+ | color: #fff; | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | 7. Crea una carpeta nova anomenada " | ||
+ | <file javascript Modal.js> | ||
+ | import React, { Component } from " | ||
+ | |||
+ | // importing all of these classes from reactstrap module | ||
+ | import { | ||
+ | Button, | ||
+ | Modal, | ||
+ | ModalHeader, | ||
+ | ModalBody, | ||
+ | ModalFooter, | ||
+ | Form, | ||
+ | FormGroup, | ||
+ | Input, | ||
+ | Label | ||
+ | } from " | ||
+ | |||
+ | 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 === " | ||
+ | value = e.target.checked; | ||
+ | } | ||
+ | const activeItem = { ...this.state.activeItem, | ||
+ | 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}> | ||
+ | < | ||
+ | < | ||
+ | |||
+ | < | ||
+ | |||
+ | {/* 3 formgroups | ||
+ | 1 title label */} | ||
+ | < | ||
+ | <Label for=" | ||
+ | <Input | ||
+ | type=" | ||
+ | name=" | ||
+ | value={this.state.activeItem.title} | ||
+ | onChange={this.handleChange} | ||
+ | placeholder=" | ||
+ | /> | ||
+ | </ | ||
+ | |||
+ | {/* 2 description label */} | ||
+ | < | ||
+ | <Label for=" | ||
+ | <Input | ||
+ | type=" | ||
+ | name=" | ||
+ | value={this.state.activeItem.description} | ||
+ | onChange={this.handleChange} | ||
+ | placeholder=" | ||
+ | /> | ||
+ | </ | ||
+ | |||
+ | {/* 3 completed label */} | ||
+ | < | ||
+ | <Label for=" | ||
+ | <Input | ||
+ | type=" | ||
+ | name=" | ||
+ | checked={this.state.activeItem.completed} | ||
+ | onChange={this.handleChange} | ||
+ | /> | ||
+ | Completed | ||
+ | </ | ||
+ | </ | ||
+ | </ | ||
+ | </ | ||
+ | {/* create a modal footer */} | ||
+ | < | ||
+ | <Button color=" | ||
+ | Save | ||
+ | </ | ||
+ | </ | ||
+ | </ | ||
+ | ); | ||
+ | } | ||
+ | } | ||
+ | export default CustomModal | ||
+ | </ | ||
+ | 8. Fes els canvis indicats a continuació al fitxer // | ||
+ | <file javascript index.js> | ||
+ | import React from " | ||
+ | import ReactDOM from " | ||
+ | import " | ||
+ | import App from " | ||
+ | |||
+ | import " | ||
+ | |||
+ | ReactDOM.render( | ||
+ | < | ||
+ | <App /> | ||
+ | </ | ||
+ | document.getElementById(" | ||
+ | ); | ||
+ | </ | ||
+ | 9. Per fer les peticions als endpoints de l'API al servidor del framework de Django, necessitarem instal·lar l' | ||
+ | < | ||
+ | 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. | ||
+ | |||
+ | <WRAP todo> | ||
+ | **Exercici: | ||
+ | Aplica la serialització de manera que es puguin gestionar els comptes associats als clients. | ||
+ | </ | ||
+ | |||
+ | \\ | ||
+ |