SlideShare a Scribd company logo
1 of 43
Download to read offline
Django Tricks
José Ignacio Galarza @igalarzab
 Carlos Hernando @chernando
django crispy forms
https://github.com/maraujop/django-crispy-forms
Crispy forms!
{% load crispy_forms_tags %}

<form method="post" class="form-horizontal">
  {{ my_formset|crispy }}
</form>
Crispy forms!
{% load crispy_forms_tags %}

<form method="post" class="form-horizontal">
  {{ my_formset|crispy }}
</form>

El formulario es compatible Twitter Bootstrap
Un formulario
from crispy_forms.helper import FormHelper

class ExampleForm(forms.Form):
   [...]
   def __init__(self, *args, **kwargs):
      self.helper = FormHelper()
      super(ExampleForm, self).__init__(*args,
**kwargs)
Personalizamos el formulario


[...]
self.helper.form_id = 'id-exampleForm'
self.helper.form_class = 'blueForms'
self.helper.form_method = 'post'
self.helper.form_action = 'submit_survey'
self.helper.add_input(Submit('submit', 'Submit'))
Y el template queda
{% load crispy_forms_tags %}

{% crispy example_form %}
Aún más personalizado
from crispy_forms.layout import Layout, Fieldset, ButtonHolder,
Submit

    self.helper.layout = Layout(
      Fieldset(
         'first arg is the legend of the fieldset',
         'field1',
         'field2'
      ),
      ButtonHolder(
         Submit('submit', 'Submit', css_class='button white')
      )
Y el template queda igual
{% load crispy_forms_tags %}

{% crispy example_form %}




           WIN
Más de crispy forms
FormSets
Cambiar layouts al vuelo
Personalizar... todo :-)




http://django-crispy-forms.readthedocs.org/
south
Nuestro modelo cambia
class Persona(models.Model):
   nombre = models.CharField(...)
   apellidos = models.CharField(...)
Nuestro modelo cambia
class Persona(models.Model):
   nombre = models.CharField(...)
   apellidos = models.CharField(...)
   email = models.EmailField(...)
Ok, hago un syncdb :)
./manage.py syncdb
Creating tables ...
Creating table tutsouth_persona
Installing custom SQL ...
Installing indexes ...
Installed 0 object(s) from 0 fixture(s)

:-D
Pero...
>>> p = Persona()
>>> p.save()
Traceback (most recent call last):
...
DatabaseError: table tutsouth_persona has no
column named email

;-(
syncdb no modifica




         FAIL
Soluciones
Django
  ○ Borrón y cuenta nueva
     manage flush && manage syncdb
  ○ Modificar manualmente las tablas
     manage sql
Soluciones
Django
  ○ Borrón y cuenta nueva
        manage flush && manage syncdb
  ○ Modificar manualmente las tablas
        manage sql

South
south
South brings migrations to Django applications.

  ●   Automatic migration creation
  ●   Database independence
  ●   App-savvy
  ●   VCS-proof
Migraciones
RAE:
  Acción y efecto de pasar de un país a otro para
  establecerse en él.

south:
   [...] a way of changing your database schema
   from one version into another [...]
Migraciones
RAE:
  Acción y efecto de pasar de un país a otro para
  establecerse en él.

south:
   [...] a way of changing your database schema
   from one version into another [...]
   En ambos sentidos.
south en dos patadas
Migraciones:
  Primera:
  manage.py schemamigration APP --initial

  Siguientes:
  manage.py schemamigration APP --auto

Aplicar:
  manage.py migrate [APP]
Migraciones complicadas
? The field 'Votacion.autor' does not have a default specified, yet
is NOT NULL.
? Since you are making this field non-nullable, you MUST specify
a default
? value to use for existing rows. Would you like to:
? 1. Quit now, and add a default to the field in models.py
? 2. Specify a one-off value to use for existing columns now
? Please select a choice:
Durante el desarrollo
Reutilizar la migración:
  manage.py schemamigration --update --auto

Conflictos
  manage.py migrate --merge

Listar:
   manage.py migrate --list
Más cosas interesantes
Datamigrations
ORM Freezing
Dependencias
...




http://south.readthedocs.org/
Pruebas :-?

● When you’re writing new code, you can use
  tests to validate your code works as expected.

● When you’re refactoring or modifying old code,
  you can use tests to ensure your changes haven’
  t affected your application’s behavior
  unexpectedly.
Pruebas :-?

● When you’re writing new code, you can use
  tests to validate your code works as expected.

● When you’re refactoring or modifying old code,
  you can use tests to ensure your changes haven’
  t affected your application’s behavior
  unexpectedly.

               Sí o sí 0:-)
Métodos disponibles
unittest
   class MyFuncTestCase(unittest.TestCase):
      def testBasic(self):
         a = ['larry', 'curly', 'moe']
         self.assertEqual(my_func(a, 0), 'larry')
doctest
   def my_func(a_list, idx):
      """
      >>> a = ['larry', 'curly', 'moe']
      >>> my_func(a, 0)
      'larry'
unittest
Forma parte de Python

Cumplir dos condiciones:
  a. Heredar de unittest.TestCase
  b. El método empieza por test


Django enriquece con django.utils.unittest
Ejemplo
import unittest

class TestDePrueba(unittest.TestCase):

  def test_prueba_1_1(self):
    self.assertEquals(1 + 1, 2)

  def test_con_error(self):
    self.assertEquals(1 + 1, 2.1, "Intel detected!")
Pruebas en Django
Por defecto:
  APP/tests.py



manage.py test [[[APP].TestCase].test_method]
Modelos
Bases de datos de prueba
  By default the test databases get their names by
  prepending test_ to the value of the NAME
  settings for the databases defined in
  DATABASES.

Ejercicio para el lector: fixtures
Vistas
Test Client simula un navegador

from django.test.client import Client

class SimpleTest(unittest.TestCase):
   def setUp(self):
     self.client = Client()

  def test_details(self):
    response = self.client.get('/customer/details/')
    self.assertEqual(response.status_code, 200)
    self.assertEqual(len(response.context['customers']), 5)
Selenium
Utiliza un navegador real

  1. Acciones que realiza
  2. Cosas que espera encontrar
Introducción a Python + Selenium
from selenium import webdriver
from selenium.webdriver.common.keys import Keys

driver = webdriver.Firefox()
driver.get("http://www.python.org")
assert "Python" in driver.title
elem = driver.find_element_by_name("q")
elem.send_keys("selenium")
elem.send_keys(Keys.RETURN)
assert "Google" in driver.title
driver.close()
Django + Selenium
from django.test import LiveServerTestCase
from selenium.webdriver.firefox.webdriver import WebDriver
class MySeleniumTests(LiveServerTestCase):
   @classmethod
   def setUpClass(cls):
     cls.selenium = WebDriver()
     super(MySeleniumTests, cls).setUpClass()
   @classmethod
   def tearDownClass(cls):
     cls.selenium.quit()
     super(MySeleniumTests, cls).tearDownClass()
Django + Selenium
def test_home(self):
   self.selenium.get(self.live_server_url)
   votacion = self.selenium.
   find_element_by_link_text("Nueva")
   self.assertIsNotNone(votacion)
   votacion.click()
   self.selenium.save_screenshot('votacion.png')
Django + Selenium
self.selenium.get('%s%s' % (self.live_server_url,
'/nueva_votacion/'))

titulo_input = self.selenium.find_element_by_id("id_titulo")
titulo_input.send_keys('prueba selenium')
autor_input = self.selenium.find_element_by_id("id_autor")
autor_input.send_keys('selenium')
self.selenium.find_element_by_id('enviar').click()
self.selenium.save_screenshot('nueva_votacion.png')
titulo = self.selenium.find_element_by_id('titulo')
self.assertEquals(titulo.text, 'prueba selenium')
Finalizando
   @8-)
Más...


            33 projects that make
            developing django apps
            awesome


http://elweb.co/programacion/33-projects-that-make-developing-django-apps-awesome/
Preguntas
   :-?
Gracias a todos!
       :-D

More Related Content

What's hot

What's hot (20)

Vuejs testing
Vuejs testingVuejs testing
Vuejs testing
 
Rails is not just Ruby
Rails is not just RubyRails is not just Ruby
Rails is not just Ruby
 
Angular 2 Architecture
Angular 2 ArchitectureAngular 2 Architecture
Angular 2 Architecture
 
Javascript Test Automation Workshop (21.08.2014)
Javascript Test Automation Workshop (21.08.2014)Javascript Test Automation Workshop (21.08.2014)
Javascript Test Automation Workshop (21.08.2014)
 
Routing And Navigation
Routing And NavigationRouting And Navigation
Routing And Navigation
 
Tango with django
Tango with djangoTango with django
Tango with django
 
Excellent
ExcellentExcellent
Excellent
 
Introduction to Protractor
Introduction to ProtractorIntroduction to Protractor
Introduction to Protractor
 
RSpec
RSpecRSpec
RSpec
 
Owl: The New Odoo UI Framework
Owl: The New Odoo UI FrameworkOwl: The New Odoo UI Framework
Owl: The New Odoo UI Framework
 
Component lifecycle hooks in Angular 2.0
Component lifecycle hooks in Angular 2.0Component lifecycle hooks in Angular 2.0
Component lifecycle hooks in Angular 2.0
 
Advanced Jasmine - Front-End JavaScript Unit Testing
Advanced Jasmine - Front-End JavaScript Unit TestingAdvanced Jasmine - Front-End JavaScript Unit Testing
Advanced Jasmine - Front-End JavaScript Unit Testing
 
Testing My Patience
Testing My PatienceTesting My Patience
Testing My Patience
 
Intro to testing Javascript with jasmine
Intro to testing Javascript with jasmineIntro to testing Javascript with jasmine
Intro to testing Javascript with jasmine
 
The Django Book - Chapter 5: Models
The Django Book - Chapter 5: ModelsThe Django Book - Chapter 5: Models
The Django Book - Chapter 5: Models
 
Тестирование и Django
Тестирование и DjangoТестирование и Django
Тестирование и Django
 
Testing JavaScript Applications
Testing JavaScript ApplicationsTesting JavaScript Applications
Testing JavaScript Applications
 
Polyglot automation - QA Fest - 2015
Polyglot automation - QA Fest - 2015Polyglot automation - QA Fest - 2015
Polyglot automation - QA Fest - 2015
 
Php Unit With Zend Framework Zendcon09
Php Unit With Zend Framework   Zendcon09Php Unit With Zend Framework   Zendcon09
Php Unit With Zend Framework Zendcon09
 
My Top 5 APEX JavaScript API's
My Top 5 APEX JavaScript API'sMy Top 5 APEX JavaScript API's
My Top 5 APEX JavaScript API's
 

Viewers also liked (6)

6º laboratorio de análisis químico 06
6º laboratorio de análisis químico   066º laboratorio de análisis químico   06
6º laboratorio de análisis químico 06
 
Ácidos, bases e indicadores
Ácidos, bases e indicadoresÁcidos, bases e indicadores
Ácidos, bases e indicadores
 
6º laboratorio de análisis químico 01
6º laboratorio de análisis químico   016º laboratorio de análisis químico   01
6º laboratorio de análisis químico 01
 
Indicadores Quimicos De Acido Base Yeny Pulido
Indicadores Quimicos De Acido Base  Yeny PulidoIndicadores Quimicos De Acido Base  Yeny Pulido
Indicadores Quimicos De Acido Base Yeny Pulido
 
Practica 4 identificación de cationes.
Practica 4 identificación de cationes.Practica 4 identificación de cationes.
Practica 4 identificación de cationes.
 
Presentacion indicadores
Presentacion indicadoresPresentacion indicadores
Presentacion indicadores
 

Similar to Django tricks (2)

django_introduction20141030
django_introduction20141030django_introduction20141030
django_introduction20141030
Kevin Wu
 
gDayX 2013 - Advanced AngularJS - Nicolas Embleton
gDayX 2013 - Advanced AngularJS - Nicolas EmbletongDayX 2013 - Advanced AngularJS - Nicolas Embleton
gDayX 2013 - Advanced AngularJS - Nicolas Embleton
George Nguyen
 
Intro To JavaScript Unit Testing - Ran Mizrahi
Intro To JavaScript Unit Testing - Ran MizrahiIntro To JavaScript Unit Testing - Ran Mizrahi
Intro To JavaScript Unit Testing - Ran Mizrahi
Ran Mizrahi
 

Similar to Django tricks (2) (20)

Performance and Scalability Testing with Python and Multi-Mechanize
Performance and Scalability Testing with Python and Multi-MechanizePerformance and Scalability Testing with Python and Multi-Mechanize
Performance and Scalability Testing with Python and Multi-Mechanize
 
Engitec - Minicurso de Django
Engitec - Minicurso de DjangoEngitec - Minicurso de Django
Engitec - Minicurso de Django
 
Introduction to Django
Introduction to DjangoIntroduction to Django
Introduction to Django
 
django_introduction20141030
django_introduction20141030django_introduction20141030
django_introduction20141030
 
Django web framework
Django web frameworkDjango web framework
Django web framework
 
Django for Beginners
Django for BeginnersDjango for Beginners
Django for Beginners
 
Mini Curso Django Ii Congresso Academico Ces
Mini Curso Django Ii Congresso Academico CesMini Curso Django Ii Congresso Academico Ces
Mini Curso Django Ii Congresso Academico Ces
 
Behind the curtain - How Django handles a request
Behind the curtain - How Django handles a requestBehind the curtain - How Django handles a request
Behind the curtain - How Django handles a request
 
Useful practices of creation automatic tests by using cucumber jvm
Useful practices of creation automatic tests by using cucumber jvmUseful practices of creation automatic tests by using cucumber jvm
Useful practices of creation automatic tests by using cucumber jvm
 
LvivPy - Flask in details
LvivPy - Flask in detailsLvivPy - Flask in details
LvivPy - Flask in details
 
Basics of AngularJS
Basics of AngularJSBasics of AngularJS
Basics of AngularJS
 
Django for mobile applications
Django for mobile applicationsDjango for mobile applications
Django for mobile applications
 
using Mithril.js + postgREST to build and consume API's
using Mithril.js + postgREST to build and consume API'susing Mithril.js + postgREST to build and consume API's
using Mithril.js + postgREST to build and consume API's
 
Building and deploying React applications
Building and deploying React applicationsBuilding and deploying React applications
Building and deploying React applications
 
gDayX 2013 - Advanced AngularJS - Nicolas Embleton
gDayX 2013 - Advanced AngularJS - Nicolas EmbletongDayX 2013 - Advanced AngularJS - Nicolas Embleton
gDayX 2013 - Advanced AngularJS - Nicolas Embleton
 
Django
DjangoDjango
Django
 
Intro To JavaScript Unit Testing - Ran Mizrahi
Intro To JavaScript Unit Testing - Ran MizrahiIntro To JavaScript Unit Testing - Ran Mizrahi
Intro To JavaScript Unit Testing - Ran Mizrahi
 
What's new in Django 1.7
What's new in Django 1.7What's new in Django 1.7
What's new in Django 1.7
 
Angular Intermediate
Angular IntermediateAngular Intermediate
Angular Intermediate
 
Hadoop cluster performance profiler
Hadoop cluster performance profilerHadoop cluster performance profiler
Hadoop cluster performance profiler
 

More from Carlos Hernando

More from Carlos Hernando (8)

Introduciendo Serverless en Proyectos Python
Introduciendo Serverless en Proyectos PythonIntroduciendo Serverless en Proyectos Python
Introduciendo Serverless en Proyectos Python
 
Microservicos: Cuándo y Cómo
Microservicos: Cuándo y CómoMicroservicos: Cuándo y Cómo
Microservicos: Cuándo y Cómo
 
Try AngularJS
Try AngularJSTry AngularJS
Try AngularJS
 
Metodologías Ágiles
Metodologías ÁgilesMetodologías Ágiles
Metodologías Ágiles
 
Bases de Datos en Java - Intro a Hibernate
Bases de Datos en Java - Intro a HibernateBases de Datos en Java - Intro a Hibernate
Bases de Datos en Java - Intro a Hibernate
 
Bases de Datos en Java - Intro a JDBC
Bases de Datos en Java - Intro a JDBCBases de Datos en Java - Intro a JDBC
Bases de Datos en Java - Intro a JDBC
 
Introducción rápida a SQL
Introducción rápida a SQLIntroducción rápida a SQL
Introducción rápida a SQL
 
Persistencia en Java - Serialización
Persistencia en Java - SerializaciónPersistencia en Java - Serialización
Persistencia en Java - Serialización
 

Recently uploaded

Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 

Recently uploaded (20)

Vector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptxVector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptx
 
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot ModelMcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf
 
Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with Milvus
 
Platformless Horizons for Digital Adaptability
Platformless Horizons for Digital AdaptabilityPlatformless Horizons for Digital Adaptability
Platformless Horizons for Digital Adaptability
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
 
Introduction to Multilingual Retrieval Augmented Generation (RAG)
Introduction to Multilingual Retrieval Augmented Generation (RAG)Introduction to Multilingual Retrieval Augmented Generation (RAG)
Introduction to Multilingual Retrieval Augmented Generation (RAG)
 
WSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering DevelopersWSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering Developers
 
Six Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal OntologySix Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal Ontology
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 

Django tricks (2)

  • 1. Django Tricks José Ignacio Galarza @igalarzab Carlos Hernando @chernando
  • 3. Crispy forms! {% load crispy_forms_tags %} <form method="post" class="form-horizontal"> {{ my_formset|crispy }} </form>
  • 4. Crispy forms! {% load crispy_forms_tags %} <form method="post" class="form-horizontal"> {{ my_formset|crispy }} </form> El formulario es compatible Twitter Bootstrap
  • 5. Un formulario from crispy_forms.helper import FormHelper class ExampleForm(forms.Form): [...] def __init__(self, *args, **kwargs): self.helper = FormHelper() super(ExampleForm, self).__init__(*args, **kwargs)
  • 6. Personalizamos el formulario [...] self.helper.form_id = 'id-exampleForm' self.helper.form_class = 'blueForms' self.helper.form_method = 'post' self.helper.form_action = 'submit_survey' self.helper.add_input(Submit('submit', 'Submit'))
  • 7. Y el template queda {% load crispy_forms_tags %} {% crispy example_form %}
  • 8. Aún más personalizado from crispy_forms.layout import Layout, Fieldset, ButtonHolder, Submit self.helper.layout = Layout( Fieldset( 'first arg is the legend of the fieldset', 'field1', 'field2' ), ButtonHolder( Submit('submit', 'Submit', css_class='button white') )
  • 9. Y el template queda igual {% load crispy_forms_tags %} {% crispy example_form %} WIN
  • 10. Más de crispy forms FormSets Cambiar layouts al vuelo Personalizar... todo :-) http://django-crispy-forms.readthedocs.org/
  • 11. south
  • 12. Nuestro modelo cambia class Persona(models.Model): nombre = models.CharField(...) apellidos = models.CharField(...)
  • 13. Nuestro modelo cambia class Persona(models.Model): nombre = models.CharField(...) apellidos = models.CharField(...) email = models.EmailField(...)
  • 14. Ok, hago un syncdb :) ./manage.py syncdb Creating tables ... Creating table tutsouth_persona Installing custom SQL ... Installing indexes ... Installed 0 object(s) from 0 fixture(s) :-D
  • 15. Pero... >>> p = Persona() >>> p.save() Traceback (most recent call last): ... DatabaseError: table tutsouth_persona has no column named email ;-(
  • 17. Soluciones Django ○ Borrón y cuenta nueva manage flush && manage syncdb ○ Modificar manualmente las tablas manage sql
  • 18. Soluciones Django ○ Borrón y cuenta nueva manage flush && manage syncdb ○ Modificar manualmente las tablas manage sql South
  • 19. south South brings migrations to Django applications. ● Automatic migration creation ● Database independence ● App-savvy ● VCS-proof
  • 20. Migraciones RAE: Acción y efecto de pasar de un país a otro para establecerse en él. south: [...] a way of changing your database schema from one version into another [...]
  • 21. Migraciones RAE: Acción y efecto de pasar de un país a otro para establecerse en él. south: [...] a way of changing your database schema from one version into another [...] En ambos sentidos.
  • 22. south en dos patadas Migraciones: Primera: manage.py schemamigration APP --initial Siguientes: manage.py schemamigration APP --auto Aplicar: manage.py migrate [APP]
  • 23. Migraciones complicadas ? The field 'Votacion.autor' does not have a default specified, yet is NOT NULL. ? Since you are making this field non-nullable, you MUST specify a default ? value to use for existing rows. Would you like to: ? 1. Quit now, and add a default to the field in models.py ? 2. Specify a one-off value to use for existing columns now ? Please select a choice:
  • 24. Durante el desarrollo Reutilizar la migración: manage.py schemamigration --update --auto Conflictos manage.py migrate --merge Listar: manage.py migrate --list
  • 25. Más cosas interesantes Datamigrations ORM Freezing Dependencias ... http://south.readthedocs.org/
  • 26.
  • 27. Pruebas :-? ● When you’re writing new code, you can use tests to validate your code works as expected. ● When you’re refactoring or modifying old code, you can use tests to ensure your changes haven’ t affected your application’s behavior unexpectedly.
  • 28. Pruebas :-? ● When you’re writing new code, you can use tests to validate your code works as expected. ● When you’re refactoring or modifying old code, you can use tests to ensure your changes haven’ t affected your application’s behavior unexpectedly. Sí o sí 0:-)
  • 29. Métodos disponibles unittest class MyFuncTestCase(unittest.TestCase): def testBasic(self): a = ['larry', 'curly', 'moe'] self.assertEqual(my_func(a, 0), 'larry') doctest def my_func(a_list, idx): """ >>> a = ['larry', 'curly', 'moe'] >>> my_func(a, 0) 'larry'
  • 30. unittest Forma parte de Python Cumplir dos condiciones: a. Heredar de unittest.TestCase b. El método empieza por test Django enriquece con django.utils.unittest
  • 31. Ejemplo import unittest class TestDePrueba(unittest.TestCase): def test_prueba_1_1(self): self.assertEquals(1 + 1, 2) def test_con_error(self): self.assertEquals(1 + 1, 2.1, "Intel detected!")
  • 32. Pruebas en Django Por defecto: APP/tests.py manage.py test [[[APP].TestCase].test_method]
  • 33. Modelos Bases de datos de prueba By default the test databases get their names by prepending test_ to the value of the NAME settings for the databases defined in DATABASES. Ejercicio para el lector: fixtures
  • 34. Vistas Test Client simula un navegador from django.test.client import Client class SimpleTest(unittest.TestCase): def setUp(self): self.client = Client() def test_details(self): response = self.client.get('/customer/details/') self.assertEqual(response.status_code, 200) self.assertEqual(len(response.context['customers']), 5)
  • 35. Selenium Utiliza un navegador real 1. Acciones que realiza 2. Cosas que espera encontrar
  • 36. Introducción a Python + Selenium from selenium import webdriver from selenium.webdriver.common.keys import Keys driver = webdriver.Firefox() driver.get("http://www.python.org") assert "Python" in driver.title elem = driver.find_element_by_name("q") elem.send_keys("selenium") elem.send_keys(Keys.RETURN) assert "Google" in driver.title driver.close()
  • 37. Django + Selenium from django.test import LiveServerTestCase from selenium.webdriver.firefox.webdriver import WebDriver class MySeleniumTests(LiveServerTestCase): @classmethod def setUpClass(cls): cls.selenium = WebDriver() super(MySeleniumTests, cls).setUpClass() @classmethod def tearDownClass(cls): cls.selenium.quit() super(MySeleniumTests, cls).tearDownClass()
  • 38. Django + Selenium def test_home(self): self.selenium.get(self.live_server_url) votacion = self.selenium. find_element_by_link_text("Nueva") self.assertIsNotNone(votacion) votacion.click() self.selenium.save_screenshot('votacion.png')
  • 39. Django + Selenium self.selenium.get('%s%s' % (self.live_server_url, '/nueva_votacion/')) titulo_input = self.selenium.find_element_by_id("id_titulo") titulo_input.send_keys('prueba selenium') autor_input = self.selenium.find_element_by_id("id_autor") autor_input.send_keys('selenium') self.selenium.find_element_by_id('enviar').click() self.selenium.save_screenshot('nueva_votacion.png') titulo = self.selenium.find_element_by_id('titulo') self.assertEquals(titulo.text, 'prueba selenium')
  • 40. Finalizando @8-)
  • 41. Más... 33 projects that make developing django apps awesome http://elweb.co/programacion/33-projects-that-make-developing-django-apps-awesome/
  • 42. Preguntas :-?