Django tricks (2)

1,019 views

Published on

Curso de aplicaciones adicionales a tener en cuenta para un proyecto Django:
* django-crispy-forms
* south
* Pruebas y Selenium

Published in: Technology
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
1,019
On SlideShare
0
From Embeds
0
Number of Embeds
9
Actions
Shares
0
Downloads
13
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

Django tricks (2)

  1. 1. Django TricksJosé Ignacio Galarza @igalarzab Carlos Hernando @chernando
  2. 2. django crispy formshttps://github.com/maraujop/django-crispy-forms
  3. 3. Crispy forms!{% load crispy_forms_tags %}<form method="post" class="form-horizontal"> {{ my_formset|crispy }}</form>
  4. 4. Crispy forms!{% load crispy_forms_tags %}<form method="post" class="form-horizontal"> {{ my_formset|crispy }}</form>El formulario es compatible Twitter Bootstrap
  5. 5. Un formulariofrom crispy_forms.helper import FormHelperclass ExampleForm(forms.Form): [...] def __init__(self, *args, **kwargs): self.helper = FormHelper() super(ExampleForm, self).__init__(*args,**kwargs)
  6. 6. Personalizamos el formulario[...]self.helper.form_id = id-exampleFormself.helper.form_class = blueFormsself.helper.form_method = postself.helper.form_action = submit_surveyself.helper.add_input(Submit(submit, Submit))
  7. 7. Y el template queda{% load crispy_forms_tags %}{% crispy example_form %}
  8. 8. Aún más personalizadofrom 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. 9. Y el template queda igual{% load crispy_forms_tags %}{% crispy example_form %} WIN
  10. 10. Más de crispy formsFormSetsCambiar layouts al vueloPersonalizar... todo :-)http://django-crispy-forms.readthedocs.org/
  11. 11. south
  12. 12. Nuestro modelo cambiaclass Persona(models.Model): nombre = models.CharField(...) apellidos = models.CharField(...)
  13. 13. Nuestro modelo cambiaclass Persona(models.Model): nombre = models.CharField(...) apellidos = models.CharField(...) email = models.EmailField(...)
  14. 14. Ok, hago un syncdb :)./manage.py syncdbCreating tables ...Creating table tutsouth_personaInstalling custom SQL ...Installing indexes ...Installed 0 object(s) from 0 fixture(s):-D
  15. 15. Pero...>>> p = Persona()>>> p.save()Traceback (most recent call last):...DatabaseError: table tutsouth_persona has nocolumn named email;-(
  16. 16. syncdb no modifica FAIL
  17. 17. SolucionesDjango ○ Borrón y cuenta nueva manage flush && manage syncdb ○ Modificar manualmente las tablas manage sql
  18. 18. SolucionesDjango ○ Borrón y cuenta nueva manage flush && manage syncdb ○ Modificar manualmente las tablas manage sqlSouth
  19. 19. southSouth brings migrations to Django applications. ● Automatic migration creation ● Database independence ● App-savvy ● VCS-proof
  20. 20. MigracionesRAE: 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. 21. MigracionesRAE: 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. 22. south en dos patadasMigraciones: Primera: manage.py schemamigration APP --initial Siguientes: manage.py schemamigration APP --autoAplicar: manage.py migrate [APP]
  23. 23. Migraciones complicadas? The field Votacion.autor does not have a default specified, yetis NOT NULL.? Since you are making this field non-nullable, you MUST specifya 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. 24. Durante el desarrolloReutilizar la migración: manage.py schemamigration --update --autoConflictos manage.py migrate --mergeListar: manage.py migrate --list
  25. 25. Más cosas interesantesDatamigrationsORM FreezingDependencias...http://south.readthedocs.org/
  26. 26. 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.
  27. 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. Sí o sí 0:-)
  28. 28. Métodos disponiblesunittest 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
  29. 29. unittestForma parte de PythonCumplir dos condiciones: a. Heredar de unittest.TestCase b. El método empieza por testDjango enriquece con django.utils.unittest
  30. 30. Ejemploimport unittestclass 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!")
  31. 31. Pruebas en DjangoPor defecto: APP/tests.pymanage.py test [[[APP].TestCase].test_method]
  32. 32. ModelosBases 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
  33. 33. VistasTest Client simula un navegadorfrom django.test.client import Clientclass 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)
  34. 34. SeleniumUtiliza un navegador real 1. Acciones que realiza 2. Cosas que espera encontrar
  35. 35. Introducción a Python + Seleniumfrom selenium import webdriverfrom selenium.webdriver.common.keys import Keysdriver = webdriver.Firefox()driver.get("http://www.python.org")assert "Python" in driver.titleelem = driver.find_element_by_name("q")elem.send_keys("selenium")elem.send_keys(Keys.RETURN)assert "Google" in driver.titledriver.close()
  36. 36. Django + Seleniumfrom django.test import LiveServerTestCasefrom selenium.webdriver.firefox.webdriver import WebDriverclass MySeleniumTests(LiveServerTestCase): @classmethod def setUpClass(cls): cls.selenium = WebDriver() super(MySeleniumTests, cls).setUpClass() @classmethod def tearDownClass(cls): cls.selenium.quit() super(MySeleniumTests, cls).tearDownClass()
  37. 37. Django + Seleniumdef 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)
  38. 38. Django + Seleniumself.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)
  39. 39. Finalizando @8-)
  40. 40. Más... 33 projects that make developing django apps awesomehttp://elweb.co/programacion/33-projects-that-make-developing-django-apps-awesome/
  41. 41. Preguntas :-?
  42. 42. Gracias a todos! :-D

×