Django + Vue, JavaScript de 3ª generación para modernizar Django

Javier Abadía
Javier Abadíahaving loads of fun as Lead Developer at StyleSage
Django + Vue.JS
JavaScript de 3ª generación para
modernizar Django
@javierabadia
PyConES 2017 Cáceres
SPAs - Single Page Applications
initial request
HTML
GET url
HTML
POST form
HTML
initial request
HTML
GET url (AJAX)
JSON
POST url (AJAX)
JSON
page
reload
Ciclo de Vida Tradicional
de una Página Web
Ciclo de Vida
de una App SPA
page
reload
GET url (AJAX)
JSON
POST url (AJAX)
JSON
El problema fundamental en el ‘front’
Frameworks de JS
1ª generación
2ª generación
3ª generación
Un poco de Vue.js
¡ Se dice /vjuː/ !
¿ Sabes que estoy
aprendiendo vue ?
Lo simple es fácil
var app = new Vue({
el: '#app',
data: {
msg: ’Hi there!',
frameworks: ['React',
'Vue.js',
'Angular.io'],
},
methods: {
isCool(framework) {
return framework === 'Vue.js';
},
},
});
<div id="app">
{{msg}}
<ul>
<li v-for="framework in frameworks">
{{framework}}
<span v-if="isCool(framework)">
, so cool!
</span>
</li>
</ul>
</div>
HTML JavaScript
Declarative Rendering
Condicionales y Bucles
Eventos
var app = new Vue({
...
methods: {
isCool(framework) {
return this.cool.indexOf(framework) !== -1;
},
toggleCool(framework) {
if( this.isCool(framework) )
this.cool.splice(this.cool.indexOf(framework),1);
else
this.cool.push(framework);
}
},
});
<ul>
<li
v-for="framework in frameworks"
@click="toggleCool(framework)">
{{framework}}
<span v-if="isCool(framework)">
, so cool!
</span>
</li>
</ul>
HTML JavaScript
Enlazando (binding) atributos
<ul>
<li class="framework-item"
:class="{cool: isCool(framework)}"
v-for="framework in frameworks"
@click="toggleCool(framework)">
{{framework}}<span v-if="isCool(framework)">, so cool!</span>
</li>
</ul>
Vue.js
Componentes
vue instances
Single-File components
// MyComponent.vue
<template>
<div></div>
</template>
<script>
export default {
data() {
return {};
},
};
</script>
<style lang="less">
</style>
js
css
webpack
(o browserify)
Single-File components
// MyComponent.vue
<template>
<div></div>
</template>
<script>
export default {
data() {
return {};
},
};
</script>
<style lang="less">
</style>
js
css
webpack
(o browserify)
Arquitectura de una SPA de Vue.js
$ vue init webpack-simple frontend
$ cd frontend
$ yarn
$ yarn run dev
localhost:8080
DEMO
1
Ejemplo: Catálogo de GIFs para IoT
http://localhost:8000/ http://localhost:8000/detail/323
La estructura clásica de Django
Vistas
Templates
Modelos
ORM
Autenticación
Middleware
Formularios
Administración
HTML
DEMO
2
Django
:8000
Webpack
:8080
La experiencia ‘óptima’ de desarrollo
• Trabajar de forma unificada
(mismo IDE)
• Desarrollo en el backend
• debugging
• breakpoints, etc
• Desarrollo en el frontend
• con agilidad
• usando Hot Module
Replacement (HMR)
El puente entre Django y Webpack
$ cd frontend
$ npm install --save-dev webpack-bundle-tracker
# (en un virtualenv, por supuesto)
$ pip install django-webpack-loader
Todo junto
var path = require('path')
var webpack = require('webpack')
var BundleTracker = require('webpack-bundle-tracker');
module.exports = {
…
plugins: [
new BundleTracker({filename: './webpack-stats.json'})
]
}
// frontend/webpack.conf.js
{% extends 'base.html' %}
{% load render_bundle from webpack_loader %}
{% block content %}
<div id="app"></div>
{% render_bundle 'main' %}
{% endblock %}
{# backend/templates/index.html #}
{
"status": "done",
"publicPath": "http://localhost:8080/dist/",
"chunks": {
"main": [
{
"name": "build.js",
"publicPath": "http://localhost:8080/dist/build.js",
"path": "/Users/jami/…/gif_catalog/frontend/dist/build.js"
}
]
}
}
// frontend/webpack-stats.json
…
WEBPACK_LOADER = {
'DEFAULT': {
'BUNDLE_DIR_NAME': 'dist/',
'STATS_FILE': os.path.join(BASE_DIR,
'frontend/webpack-stats.json'),
}
}
# settings.py
def index(request):
return render(request, 'index.html', {})
# backend/views.py
{% extends 'base.html' %}
{% load render_bundle from webpack_loader %}
{% block content %}
<div id="app"></div>
{% render_bundle 'main' %}
{% endblock %}
{# backend/templates/index.html #}
Django
:8000
Webpack
:8080
urlpatterns = [
url(r'^', views.index),
]
# backend/urls.py
App.vue
main.js
*.vue
localhost:8000/
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
…
</head>
<body>
<div id="app"></div>
<script type="text/javascript"
src="http://localhost:8080/dist/build.js">
</script>
</body
</html>
HMRbuild.js
Django + Vue, JavaScript de 3ª generación para modernizar Django
DEMO
3
Webpack: detalles de configuración
var path = require('path')
var webpack = require('webpack')
var BundleTracker = require('webpack-bundle-tracker');
module.exports = {
entry: './src/main.js',
output: {
path: path.resolve(__dirname, './dist'),
publicPath: 'http://localhost:8080/dist/',
filename: 'build.js'
},
module: {
...
},
devServer: {
historyApiFallback: true,
noInfo: true,
headers: {
'Access-Control-Allow-Origin': '*'
}
},
plugins: [
new BundleTracker({filename: './webpack-stats.json'})
]
}
url absoluta
incluyendo puerto
activar CORS para que el cliente
HMR pueda hacer peticiones al
devServer de webpack
// webpack.config.js
Django
:8000
localhost:8000/
HTML
localhost:8000/api/*
JSON
Webpack
:8080
HMR
Implementar una API ¿REST?
urlpatterns = [
url(r'^api/pics', api.pics),
url(r'^', views.index),
]
# backend/urls.py
def pics(request):
count = GifPicture.objects.all().count()
all_ids = range(count)
random.shuffle(all_ids)
picked_ids = all_ids[:18]
gif_pictures = GifPicture.objects
.filter(id__in=picked_ids)
.order_by('-upload_date')
result = {
'pics': gif_pictures,
}
return JsonResponse(result)
# backend/api.py
import axios from 'axios';
export default {
getRandomPics() {
return axios.get('/api/pics')
.then(response => {
return response.data.pics;
});
},
}
// gifPicsApi.js
Django
:8000
…
<script>
import gifPicsApi from '../services/gifPicsApi.js';
export default {
…
mounted() {
gifPicsApi.getRandomPics().then(pics => {
this.pics = pics;
});
},
};
</script>
// GifHome.vue
DEMO
4
Autenticación
Una posible implementación: 2PA
http://localhost:8000/login http://localhost:8000/*
create session
redirect
set cookie
vue-routing
Django + auth + sessions
<script>
export default {
name: 'app',
data() {
return {
msg: 'Welcome to Your Vue.js App!',
user: {},
}
},
created() {
this.user = window.user;
},
}
</script>
// App.vue
@login_required
def index(request):
context = {
'user': request.user,
}
return render(request, 'index.html', context)
# backend/views.py
{% extends 'base.html' %}
{% load render_bundle from webpack_loader %}
{% block content %}
<div id="app"></div>
<script>
var user = {
username: "{{ user.username }}",
email: "{{ user.email }}",
};
</script>
{% render_bundle 'main' %}
{% endblock %}
# backend/templates/index.html
DEMO
5
Routing
DEMO
6
Rutas
urlpatterns = [
url(r'^api/suggestions/$', api.suggestions),
url(r'^api/search/$', api.search),
url(r'^api/pics/(?P<id>[0-9]+)$', api.pic_details),
url(r'^api/pics/$', api.pics),
url(r'^', views.index),
]
# backend/urls.py
Vue.use(Router);
const router = new Router({
mode: 'history',
routes: [
{
path: '/',
name: 'home',
component: GifHome
},{
path: '/detail/:id',
name: 'detail',
component: GifDetail,
props:true
},{
path: '*',
component: Error404
}, // Not found
],
});
# router.js
urlpatterns = [
url(r'^admin/', admin.site.urls),
url('^', include('django.contrib.auth.urls')),
url(r'^', include('backend.urls'))
]
# urls.py
/login
/logout
¿Es Django el mejor backend?
código
isomórfico
server-side
rendering
async I/O
Comentarios Finales
• APIs
• REST?
• ‘a pelo’
• django-tastypie
• django-rest-framework
• GraphQL
• graphene (django)
• apollo (vue)
• (no lo he probado)
• Server Side Rendering
• nope
• seeding
• sip
• SEO
• pre-render
• inyectar contenido en Django
Conclusión
Referencias
• Doc de Vue: https://vuejs.org/v2/guide/single-file-components.html
• Doc de Webpack: https://webpack.js.org/
• SurviveJS: https://survivejs.com/webpack/
• webpack-bundle-tracker: https://github.com/ezhome/webpack-bundle-tracker
• django-webpack-loader: https://github.com/ezhome/django-webpack-loader
• hello-vue + Django project: https://github.com/rokups/hello-vue-django
• modernize Django frontend: http://owaislone.org/blog/modern-frontends-with-django/
• Django + REACT with HMR: http://owaislone.org/blog/webpack-plus-reactjs-and-django/
• Django-angular: http://django-angular.readthedocs.io/en/latest/index.html
Gracias!
@javierabadia
1 of 40

Recommended

Vue.js + Django - configuración para desarrollo con webpack y HMR by
Vue.js + Django - configuración para desarrollo con webpack y HMRVue.js + Django - configuración para desarrollo con webpack y HMR
Vue.js + Django - configuración para desarrollo con webpack y HMRJavier Abadía
3.2K views22 slides
Django - Python MVC Framework by
Django - Python MVC FrameworkDjango - Python MVC Framework
Django - Python MVC FrameworkBala Kumar
27.9K views12 slides
Spring boot Introduction by
Spring boot IntroductionSpring boot Introduction
Spring boot IntroductionJeevesh Pandey
3.1K views26 slides
PUC SE Day 2019 - SpringBoot by
PUC SE Day 2019 - SpringBootPUC SE Day 2019 - SpringBoot
PUC SE Day 2019 - SpringBootJosué Neis
697 views35 slides
Introduction to django framework by
Introduction to django frameworkIntroduction to django framework
Introduction to django frameworkKnoldus Inc.
1.2K views17 slides
Overview of React.JS - Internship Presentation - Week 5 by
Overview of React.JS - Internship Presentation - Week 5Overview of React.JS - Internship Presentation - Week 5
Overview of React.JS - Internship Presentation - Week 5Devang Garach
1.8K views34 slides

More Related Content

What's hot

Spring Boot in Action by
Spring Boot in Action Spring Boot in Action
Spring Boot in Action Alex Movila
3K views55 slides
Django for Beginners by
Django for BeginnersDjango for Beginners
Django for BeginnersJason Davies
13.1K views41 slides
Spring Boot by
Spring BootSpring Boot
Spring BootJaran Flaath
543 views51 slides
Django Introduction & Tutorial by
Django Introduction & TutorialDjango Introduction & Tutorial
Django Introduction & Tutorial之宇 趙
8.8K views144 slides
Introduction to Django by
Introduction to DjangoIntroduction to Django
Introduction to DjangoKnoldus Inc.
5.5K views24 slides
Spring boot introduction by
Spring boot introductionSpring boot introduction
Spring boot introductionRasheed Waraich
7.7K views36 slides

What's hot(20)

Spring Boot in Action by Alex Movila
Spring Boot in Action Spring Boot in Action
Spring Boot in Action
Alex Movila3K views
Django for Beginners by Jason Davies
Django for BeginnersDjango for Beginners
Django for Beginners
Jason Davies13.1K views
Django Introduction & Tutorial by 之宇 趙
Django Introduction & TutorialDjango Introduction & Tutorial
Django Introduction & Tutorial
之宇 趙8.8K views
Introduction to Django by Knoldus Inc.
Introduction to DjangoIntroduction to Django
Introduction to Django
Knoldus Inc.5.5K views
Django Framework Overview forNon-Python Developers by Rosario Renga
Django Framework Overview forNon-Python DevelopersDjango Framework Overview forNon-Python Developers
Django Framework Overview forNon-Python Developers
Rosario Renga3.1K views
Spring Framework - Spring Security by Dzmitry Naskou
Spring Framework - Spring SecuritySpring Framework - Spring Security
Spring Framework - Spring Security
Dzmitry Naskou23.5K views
Angular - Chapter 7 - HTTP Services by WebStackAcademy
Angular - Chapter 7 - HTTP ServicesAngular - Chapter 7 - HTTP Services
Angular - Chapter 7 - HTTP Services
WebStackAcademy648 views
Angular Data Binding by Duy Khanh
Angular Data BindingAngular Data Binding
Angular Data Binding
Duy Khanh707 views
REST Easy with Django-Rest-Framework by Marcel Chastain
REST Easy with Django-Rest-FrameworkREST Easy with Django-Rest-Framework
REST Easy with Django-Rest-Framework
Marcel Chastain7.5K views
Introduction to Node js by Akshay Mathur
Introduction to Node jsIntroduction to Node js
Introduction to Node js
Akshay Mathur11.7K views
Introduction to Django REST Framework, an easy way to build REST framework in... by Zhe Li
Introduction to Django REST Framework, an easy way to build REST framework in...Introduction to Django REST Framework, an easy way to build REST framework in...
Introduction to Django REST Framework, an easy way to build REST framework in...
Zhe Li2.6K views

Similar to Django + Vue, JavaScript de 3ª generación para modernizar Django

Front End Development for Back End Java Developers - Jfokus 2020 by
Front End Development for Back End Java Developers - Jfokus 2020Front End Development for Back End Java Developers - Jfokus 2020
Front End Development for Back End Java Developers - Jfokus 2020Matt Raible
181 views112 slides
Love at first Vue by
Love at first VueLove at first Vue
Love at first VueDalibor Gogic
660 views37 slides
How to Webpack your Django! by
How to Webpack your Django!How to Webpack your Django!
How to Webpack your Django!David Gibbons
2.9K views50 slides
Vue js and Dyploma by
Vue js and DyplomaVue js and Dyploma
Vue js and DyplomaYoram Kornatzky
627 views42 slides
Keeping the frontend under control with Symfony and Webpack by
Keeping the frontend under control with Symfony and WebpackKeeping the frontend under control with Symfony and Webpack
Keeping the frontend under control with Symfony and WebpackIgnacio Martín
6.4K views90 slides
Vue JS @ MindDoc. The progressive road to online therapy by
Vue JS @ MindDoc. The progressive road to online therapyVue JS @ MindDoc. The progressive road to online therapy
Vue JS @ MindDoc. The progressive road to online therapyDarío Blanco Iturriaga
183 views34 slides

Similar to Django + Vue, JavaScript de 3ª generación para modernizar Django(20)

Front End Development for Back End Java Developers - Jfokus 2020 by Matt Raible
Front End Development for Back End Java Developers - Jfokus 2020Front End Development for Back End Java Developers - Jfokus 2020
Front End Development for Back End Java Developers - Jfokus 2020
Matt Raible181 views
How to Webpack your Django! by David Gibbons
How to Webpack your Django!How to Webpack your Django!
How to Webpack your Django!
David Gibbons2.9K views
Keeping the frontend under control with Symfony and Webpack by Ignacio Martín
Keeping the frontend under control with Symfony and WebpackKeeping the frontend under control with Symfony and Webpack
Keeping the frontend under control with Symfony and Webpack
Ignacio Martín6.4K views
Serverless Angular, Material, Firebase and Google Cloud applications by Loiane Groner
Serverless Angular, Material, Firebase and Google Cloud applicationsServerless Angular, Material, Firebase and Google Cloud applications
Serverless Angular, Material, Firebase and Google Cloud applications
Loiane Groner2K views
Building and deploying React applications by Astrails
Building and deploying React applicationsBuilding and deploying React applications
Building and deploying React applications
Astrails2.1K views
09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5) by Igor Bronovskyy
09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)
09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)
Igor Bronovskyy410 views
How Bitbucket Pipelines Loads Connect UI Assets Super-fast by Atlassian
How Bitbucket Pipelines Loads Connect UI Assets Super-fastHow Bitbucket Pipelines Loads Connect UI Assets Super-fast
How Bitbucket Pipelines Loads Connect UI Assets Super-fast
Atlassian10.6K views
Bonnes pratiques de développement avec Node js by Francois Zaninotto
Bonnes pratiques de développement avec Node jsBonnes pratiques de développement avec Node js
Bonnes pratiques de développement avec Node js
Francois Zaninotto5.7K views
Universal JS Web Applications with React - Luciano Mammino - Codemotion Rome ... by Luciano Mammino
Universal JS Web Applications with React - Luciano Mammino - Codemotion Rome ...Universal JS Web Applications with React - Luciano Mammino - Codemotion Rome ...
Universal JS Web Applications with React - Luciano Mammino - Codemotion Rome ...
Luciano Mammino330 views
Universal JavaScript Web Applications with React - Luciano Mammino - Codemoti... by Codemotion
Universal JavaScript Web Applications with React - Luciano Mammino - Codemoti...Universal JavaScript Web Applications with React - Luciano Mammino - Codemoti...
Universal JavaScript Web Applications with React - Luciano Mammino - Codemoti...
Codemotion1.1K views
Heroku pop-behind-the-sense by Ben Lin
Heroku pop-behind-the-senseHeroku pop-behind-the-sense
Heroku pop-behind-the-sense
Ben Lin778 views
HTML5: huh, what is it good for? by Remy Sharp
HTML5: huh, what is it good for?HTML5: huh, what is it good for?
HTML5: huh, what is it good for?
Remy Sharp1.4K views
Building Universal Web Apps with React ForwardJS 2017 by Elyse Kolker Gordon
Building Universal Web Apps with React ForwardJS 2017Building Universal Web Apps with React ForwardJS 2017
Building Universal Web Apps with React ForwardJS 2017
How to Build SPA with Vue Router 2.0 by Takuya Tejima
How to Build SPA with Vue Router 2.0How to Build SPA with Vue Router 2.0
How to Build SPA with Vue Router 2.0
Takuya Tejima18.5K views

More from Javier Abadía

Python Asíncrono - Async Python by
Python Asíncrono - Async PythonPython Asíncrono - Async Python
Python Asíncrono - Async PythonJavier Abadía
226 views81 slides
Extendiendo Django: Cómo Escribir Tu Propio Backend de Base de Datos - Exasol by
Extendiendo Django: Cómo Escribir Tu Propio Backend de Base de Datos - ExasolExtendiendo Django: Cómo Escribir Tu Propio Backend de Base de Datos - Exasol
Extendiendo Django: Cómo Escribir Tu Propio Backend de Base de Datos - ExasolJavier Abadía
822 views52 slides
UX/UI para Desarrolladores by
UX/UI para DesarrolladoresUX/UI para Desarrolladores
UX/UI para DesarrolladoresJavier Abadía
367 views118 slides
Reactividad en Angular, React y VueJS by
Reactividad en Angular, React y VueJSReactividad en Angular, React y VueJS
Reactividad en Angular, React y VueJSJavier Abadía
2K views70 slides
Las reglas que hay que romper para que tu equipo de desarrollo sea el más RÁPIDO by
Las reglas que hay que romper para que tu equipo de desarrollo sea el más RÁPIDOLas reglas que hay que romper para que tu equipo de desarrollo sea el más RÁPIDO
Las reglas que hay que romper para que tu equipo de desarrollo sea el más RÁPIDOJavier Abadía
415 views63 slides
Retos de Programación en Python by
Retos de Programación en PythonRetos de Programación en Python
Retos de Programación en PythonJavier Abadía
1.2K views44 slides

More from Javier Abadía(11)

Python Asíncrono - Async Python by Javier Abadía
Python Asíncrono - Async PythonPython Asíncrono - Async Python
Python Asíncrono - Async Python
Javier Abadía226 views
Extendiendo Django: Cómo Escribir Tu Propio Backend de Base de Datos - Exasol by Javier Abadía
Extendiendo Django: Cómo Escribir Tu Propio Backend de Base de Datos - ExasolExtendiendo Django: Cómo Escribir Tu Propio Backend de Base de Datos - Exasol
Extendiendo Django: Cómo Escribir Tu Propio Backend de Base de Datos - Exasol
Javier Abadía822 views
Reactividad en Angular, React y VueJS by Javier Abadía
Reactividad en Angular, React y VueJSReactividad en Angular, React y VueJS
Reactividad en Angular, React y VueJS
Javier Abadía2K views
Las reglas que hay que romper para que tu equipo de desarrollo sea el más RÁPIDO by Javier Abadía
Las reglas que hay que romper para que tu equipo de desarrollo sea el más RÁPIDOLas reglas que hay que romper para que tu equipo de desarrollo sea el más RÁPIDO
Las reglas que hay que romper para que tu equipo de desarrollo sea el más RÁPIDO
Javier Abadía415 views
Retos de Programación en Python by Javier Abadía
Retos de Programación en PythonRetos de Programación en Python
Retos de Programación en Python
Javier Abadía1.2K views
Anatomía de un Bot para Resultados Electorales by Javier Abadía
Anatomía de un Bot para Resultados ElectoralesAnatomía de un Bot para Resultados Electorales
Anatomía de un Bot para Resultados Electorales
Javier Abadía469 views
Deep learning image classification aplicado al mundo de la moda by Javier Abadía
Deep learning image classification aplicado al mundo de la modaDeep learning image classification aplicado al mundo de la moda
Deep learning image classification aplicado al mundo de la moda
Javier Abadía1.3K views
Análisis de colores: cómo analizar tendencias de moda automáticamente by Javier Abadía
 Análisis de colores: cómo analizar tendencias de moda automáticamente Análisis de colores: cómo analizar tendencias de moda automáticamente
Análisis de colores: cómo analizar tendencias de moda automáticamente
Javier Abadía1.4K views
Codemotion 2016 - d3.js un taller divertido y difícil by Javier Abadía
Codemotion 2016 - d3.js un taller divertido y difícilCodemotion 2016 - d3.js un taller divertido y difícil
Codemotion 2016 - d3.js un taller divertido y difícil
Javier Abadía681 views

Recently uploaded

Voice Logger - Telephony Integration Solution at Aegis by
Voice Logger - Telephony Integration Solution at AegisVoice Logger - Telephony Integration Solution at Aegis
Voice Logger - Telephony Integration Solution at AegisNirmal Sharma
39 views1 slide
Case Study Copenhagen Energy and Business Central.pdf by
Case Study Copenhagen Energy and Business Central.pdfCase Study Copenhagen Energy and Business Central.pdf
Case Study Copenhagen Energy and Business Central.pdfAitana
16 views3 slides
Design Driven Network Assurance by
Design Driven Network AssuranceDesign Driven Network Assurance
Design Driven Network AssuranceNetwork Automation Forum
15 views42 slides
GDG Cloud Southlake 28 Brad Taylor and Shawn Augenstein Old Problems in the N... by
GDG Cloud Southlake 28 Brad Taylor and Shawn Augenstein Old Problems in the N...GDG Cloud Southlake 28 Brad Taylor and Shawn Augenstein Old Problems in the N...
GDG Cloud Southlake 28 Brad Taylor and Shawn Augenstein Old Problems in the N...James Anderson
85 views32 slides
Zero to Automated in Under a Year by
Zero to Automated in Under a YearZero to Automated in Under a Year
Zero to Automated in Under a YearNetwork Automation Forum
15 views23 slides
Unit 1_Lecture 2_Physical Design of IoT.pdf by
Unit 1_Lecture 2_Physical Design of IoT.pdfUnit 1_Lecture 2_Physical Design of IoT.pdf
Unit 1_Lecture 2_Physical Design of IoT.pdfStephenTec
12 views36 slides

Recently uploaded(20)

Voice Logger - Telephony Integration Solution at Aegis by Nirmal Sharma
Voice Logger - Telephony Integration Solution at AegisVoice Logger - Telephony Integration Solution at Aegis
Voice Logger - Telephony Integration Solution at Aegis
Nirmal Sharma39 views
Case Study Copenhagen Energy and Business Central.pdf by Aitana
Case Study Copenhagen Energy and Business Central.pdfCase Study Copenhagen Energy and Business Central.pdf
Case Study Copenhagen Energy and Business Central.pdf
Aitana16 views
GDG Cloud Southlake 28 Brad Taylor and Shawn Augenstein Old Problems in the N... by James Anderson
GDG Cloud Southlake 28 Brad Taylor and Shawn Augenstein Old Problems in the N...GDG Cloud Southlake 28 Brad Taylor and Shawn Augenstein Old Problems in the N...
GDG Cloud Southlake 28 Brad Taylor and Shawn Augenstein Old Problems in the N...
James Anderson85 views
Unit 1_Lecture 2_Physical Design of IoT.pdf by StephenTec
Unit 1_Lecture 2_Physical Design of IoT.pdfUnit 1_Lecture 2_Physical Design of IoT.pdf
Unit 1_Lecture 2_Physical Design of IoT.pdf
StephenTec12 views
ESPC 2023 - Protect and Govern your Sensitive Data with Microsoft Purview in ... by Jasper Oosterveld
ESPC 2023 - Protect and Govern your Sensitive Data with Microsoft Purview in ...ESPC 2023 - Protect and Govern your Sensitive Data with Microsoft Purview in ...
ESPC 2023 - Protect and Govern your Sensitive Data with Microsoft Purview in ...
PharoJS - Zürich Smalltalk Group Meetup November 2023 by Noury Bouraqadi
PharoJS - Zürich Smalltalk Group Meetup November 2023PharoJS - Zürich Smalltalk Group Meetup November 2023
PharoJS - Zürich Smalltalk Group Meetup November 2023
Noury Bouraqadi127 views
Piloting & Scaling Successfully With Microsoft Viva by Richard Harbridge
Piloting & Scaling Successfully With Microsoft VivaPiloting & Scaling Successfully With Microsoft Viva
Piloting & Scaling Successfully With Microsoft Viva
STPI OctaNE CoE Brochure.pdf by madhurjyapb
STPI OctaNE CoE Brochure.pdfSTPI OctaNE CoE Brochure.pdf
STPI OctaNE CoE Brochure.pdf
madhurjyapb14 views
handbook for web 3 adoption.pdf by Liveplex
handbook for web 3 adoption.pdfhandbook for web 3 adoption.pdf
handbook for web 3 adoption.pdf
Liveplex22 views
iSAQB Software Architecture Gathering 2023: How Process Orchestration Increas... by Bernd Ruecker
iSAQB Software Architecture Gathering 2023: How Process Orchestration Increas...iSAQB Software Architecture Gathering 2023: How Process Orchestration Increas...
iSAQB Software Architecture Gathering 2023: How Process Orchestration Increas...
Bernd Ruecker37 views

Django + Vue, JavaScript de 3ª generación para modernizar Django

  • 1. Django + Vue.JS JavaScript de 3ª generación para modernizar Django @javierabadia PyConES 2017 Cáceres
  • 2. SPAs - Single Page Applications initial request HTML GET url HTML POST form HTML initial request HTML GET url (AJAX) JSON POST url (AJAX) JSON page reload Ciclo de Vida Tradicional de una Página Web Ciclo de Vida de una App SPA page reload
  • 3. GET url (AJAX) JSON POST url (AJAX) JSON El problema fundamental en el ‘front’
  • 4. Frameworks de JS 1ª generación 2ª generación 3ª generación
  • 5. Un poco de Vue.js
  • 6. ¡ Se dice /vjuː/ ! ¿ Sabes que estoy aprendiendo vue ?
  • 7. Lo simple es fácil var app = new Vue({ el: '#app', data: { msg: ’Hi there!', frameworks: ['React', 'Vue.js', 'Angular.io'], }, methods: { isCool(framework) { return framework === 'Vue.js'; }, }, }); <div id="app"> {{msg}} <ul> <li v-for="framework in frameworks"> {{framework}} <span v-if="isCool(framework)"> , so cool! </span> </li> </ul> </div> HTML JavaScript Declarative Rendering Condicionales y Bucles
  • 8. Eventos var app = new Vue({ ... methods: { isCool(framework) { return this.cool.indexOf(framework) !== -1; }, toggleCool(framework) { if( this.isCool(framework) ) this.cool.splice(this.cool.indexOf(framework),1); else this.cool.push(framework); } }, }); <ul> <li v-for="framework in frameworks" @click="toggleCool(framework)"> {{framework}} <span v-if="isCool(framework)"> , so cool! </span> </li> </ul> HTML JavaScript
  • 9. Enlazando (binding) atributos <ul> <li class="framework-item" :class="{cool: isCool(framework)}" v-for="framework in frameworks" @click="toggleCool(framework)"> {{framework}}<span v-if="isCool(framework)">, so cool!</span> </li> </ul>
  • 12. Single-File components // MyComponent.vue <template> <div></div> </template> <script> export default { data() { return {}; }, }; </script> <style lang="less"> </style> js css webpack (o browserify)
  • 13. Single-File components // MyComponent.vue <template> <div></div> </template> <script> export default { data() { return {}; }, }; </script> <style lang="less"> </style> js css webpack (o browserify)
  • 14. Arquitectura de una SPA de Vue.js $ vue init webpack-simple frontend $ cd frontend $ yarn $ yarn run dev localhost:8080
  • 16. Ejemplo: Catálogo de GIFs para IoT http://localhost:8000/ http://localhost:8000/detail/323
  • 17. La estructura clásica de Django Vistas Templates Modelos ORM Autenticación Middleware Formularios Administración HTML
  • 20. La experiencia ‘óptima’ de desarrollo • Trabajar de forma unificada (mismo IDE) • Desarrollo en el backend • debugging • breakpoints, etc • Desarrollo en el frontend • con agilidad • usando Hot Module Replacement (HMR)
  • 21. El puente entre Django y Webpack $ cd frontend $ npm install --save-dev webpack-bundle-tracker # (en un virtualenv, por supuesto) $ pip install django-webpack-loader
  • 22. Todo junto var path = require('path') var webpack = require('webpack') var BundleTracker = require('webpack-bundle-tracker'); module.exports = { … plugins: [ new BundleTracker({filename: './webpack-stats.json'}) ] } // frontend/webpack.conf.js {% extends 'base.html' %} {% load render_bundle from webpack_loader %} {% block content %} <div id="app"></div> {% render_bundle 'main' %} {% endblock %} {# backend/templates/index.html #} { "status": "done", "publicPath": "http://localhost:8080/dist/", "chunks": { "main": [ { "name": "build.js", "publicPath": "http://localhost:8080/dist/build.js", "path": "/Users/jami/…/gif_catalog/frontend/dist/build.js" } ] } } // frontend/webpack-stats.json … WEBPACK_LOADER = { 'DEFAULT': { 'BUNDLE_DIR_NAME': 'dist/', 'STATS_FILE': os.path.join(BASE_DIR, 'frontend/webpack-stats.json'), } } # settings.py
  • 23. def index(request): return render(request, 'index.html', {}) # backend/views.py {% extends 'base.html' %} {% load render_bundle from webpack_loader %} {% block content %} <div id="app"></div> {% render_bundle 'main' %} {% endblock %} {# backend/templates/index.html #} Django :8000 Webpack :8080 urlpatterns = [ url(r'^', views.index), ] # backend/urls.py App.vue main.js *.vue localhost:8000/ <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> … </head> <body> <div id="app"></div> <script type="text/javascript" src="http://localhost:8080/dist/build.js"> </script> </body </html> HMRbuild.js
  • 26. Webpack: detalles de configuración var path = require('path') var webpack = require('webpack') var BundleTracker = require('webpack-bundle-tracker'); module.exports = { entry: './src/main.js', output: { path: path.resolve(__dirname, './dist'), publicPath: 'http://localhost:8080/dist/', filename: 'build.js' }, module: { ... }, devServer: { historyApiFallback: true, noInfo: true, headers: { 'Access-Control-Allow-Origin': '*' } }, plugins: [ new BundleTracker({filename: './webpack-stats.json'}) ] } url absoluta incluyendo puerto activar CORS para que el cliente HMR pueda hacer peticiones al devServer de webpack // webpack.config.js
  • 28. Implementar una API ¿REST? urlpatterns = [ url(r'^api/pics', api.pics), url(r'^', views.index), ] # backend/urls.py def pics(request): count = GifPicture.objects.all().count() all_ids = range(count) random.shuffle(all_ids) picked_ids = all_ids[:18] gif_pictures = GifPicture.objects .filter(id__in=picked_ids) .order_by('-upload_date') result = { 'pics': gif_pictures, } return JsonResponse(result) # backend/api.py import axios from 'axios'; export default { getRandomPics() { return axios.get('/api/pics') .then(response => { return response.data.pics; }); }, } // gifPicsApi.js Django :8000 … <script> import gifPicsApi from '../services/gifPicsApi.js'; export default { … mounted() { gifPicsApi.getRandomPics().then(pics => { this.pics = pics; }); }, }; </script> // GifHome.vue
  • 30. Autenticación Una posible implementación: 2PA http://localhost:8000/login http://localhost:8000/* create session redirect set cookie vue-routing
  • 31. Django + auth + sessions <script> export default { name: 'app', data() { return { msg: 'Welcome to Your Vue.js App!', user: {}, } }, created() { this.user = window.user; }, } </script> // App.vue @login_required def index(request): context = { 'user': request.user, } return render(request, 'index.html', context) # backend/views.py {% extends 'base.html' %} {% load render_bundle from webpack_loader %} {% block content %} <div id="app"></div> <script> var user = { username: "{{ user.username }}", email: "{{ user.email }}", }; </script> {% render_bundle 'main' %} {% endblock %} # backend/templates/index.html
  • 35. Rutas urlpatterns = [ url(r'^api/suggestions/$', api.suggestions), url(r'^api/search/$', api.search), url(r'^api/pics/(?P<id>[0-9]+)$', api.pic_details), url(r'^api/pics/$', api.pics), url(r'^', views.index), ] # backend/urls.py Vue.use(Router); const router = new Router({ mode: 'history', routes: [ { path: '/', name: 'home', component: GifHome },{ path: '/detail/:id', name: 'detail', component: GifDetail, props:true },{ path: '*', component: Error404 }, // Not found ], }); # router.js urlpatterns = [ url(r'^admin/', admin.site.urls), url('^', include('django.contrib.auth.urls')), url(r'^', include('backend.urls')) ] # urls.py /login /logout
  • 36. ¿Es Django el mejor backend? código isomórfico server-side rendering async I/O
  • 37. Comentarios Finales • APIs • REST? • ‘a pelo’ • django-tastypie • django-rest-framework • GraphQL • graphene (django) • apollo (vue) • (no lo he probado) • Server Side Rendering • nope • seeding • sip • SEO • pre-render • inyectar contenido en Django
  • 39. Referencias • Doc de Vue: https://vuejs.org/v2/guide/single-file-components.html • Doc de Webpack: https://webpack.js.org/ • SurviveJS: https://survivejs.com/webpack/ • webpack-bundle-tracker: https://github.com/ezhome/webpack-bundle-tracker • django-webpack-loader: https://github.com/ezhome/django-webpack-loader • hello-vue + Django project: https://github.com/rokups/hello-vue-django • modernize Django frontend: http://owaislone.org/blog/modern-frontends-with-django/ • Django + REACT with HMR: http://owaislone.org/blog/webpack-plus-reactjs-and-django/ • Django-angular: http://django-angular.readthedocs.io/en/latest/index.html

Editor's Notes

  1. v-if también hay v-show
  2. como el ng-click funciona con todos los eventos: @hover @load ver las herramientas de desarrollo
  3. $ npm install -g vue-cli $ vue init webpack-simple my-project $ cd my-project $ npm install $ npm run dev
  4. $ npm install -g vue-cli $ vue init webpack-simple my-project $ cd my-project $ npm install $ npm run dev
  5. webpack HMR DevTools ver el index.html
  6. Vistas, Templates ORM, Modelos: migraciones, esquemas… Middleware, Autenticación Formularios, Administración Django has neatly packaged the best of web development in a very convenient project
  7. yo uso PyCharm pero funciona igual lanzando los comandos desde el terminal y usando SublimeText u otro editor
  8. webpack-bundle-tracker plug-in de webpack genera un fichero ’webpack-stats.json’ con los resultados de la compilación django-webpack-loader módulo de django lee el fichero ‘webpack-stats.json’ y renderiza las tags <script> apropiadas en una plantilla de Django Django debe servir el index.html de nuestra app El index.html ‘tira’ de los bundles generados por webpack webpack escucha, implementa HMR
  9. En el servidor Simplemente usar JsonResponse() Django REST Framework no es necesario experiencia similar a los formularios de Django En el cliente axios
  10. Django sirve 2 vistas vista de login vista de SPA Django mantiene las sesiones que se comparten con el cliente mediante una cookie Django comprueba la cookie/sesión en cada llamada podemos embeber la identidad en la plantilla Hay otras formas SPA -> TokenAuthentication (Django REST Framework) Types of authentication SessionAuthentication TokenAuthentication … https://stackoverflow.com/a/27582256/79536 http://www.django-rest-framework.org/topics/ajax-csrf-cors/
  11. la vista principal tiene un <router-view></router-view> el router selecciona un componente para renderizar en ese punto a partir de la URL y mucho más: rutas anidadas, parámetros, guardas…
  12. Django devuelve lo mismo para todas las rutas El vue-router selecciona la vista correcta
  13. node es la elección natural cuando pensamos en un backend para vue un solo lenguaje isomorphic code server-side-rendering async I/O django Django has neatly packaged the best of web development in a very convenient project Access to other libs p.ej. pandas, machine learning, image recognition, ORM… laravel: default front-end for laravel (Jul 2016), made the framework take off
  14. https://www.pydanny.com/choosing-an-api-framework-for-django.html https://django-tastypie.readthedocs.io/en/latest/ http://www.django-rest-framework.org/ https://github.com/graphql-python/graphene https://vuejsdevelopers.com/2017/04/01/vue-js-prerendering-node-laravel/