Cinco Paquetes De Django Que Amamos En Monadical - HedgeDoc
  1388 views
<center> Cinco Paquetes De Django Que Amamos En Monadical === *Escrito por Karim. Original publicado el 2021-03-02 en el [Blog de Monadical](https://monadical.com/blog.html).* </center> Uno de los mayores atractivos de Django es su ecosistema. Si se presenta algún problema existen muchas posibilidades de que alguien en la comunidad también lo haya tenido, y fuera tan amable de abstraerlo en un paquete reutilizable y publicarlo para la comunidad. Aquí encontrará cinco paquetes muy útiles que usamos con regularidad en Monadical. ## 1 [django-polymorphic](https://github.com/django-polymorphic/django-polymorphic) En la programación orientada a objetos usamos el término "polimorfismo" para referirnos a objetos que comparten una interfaz pero no la implementación. Un ejemplo pedagógico común es el que resulta de modelar un animal como un objeto: Los perros y los gatos producen un sonido que se puede invocar con la misma función `animal.sonido()`--pero el sonido es diferente. Un ejemplo más práctico resulta con los items de una tienda online: Los items comparten algunas características pero difieren en otras. Existe un [artículo excelente en Real Python](https://realpython.com/modeling-polymorphism-django-python) que presenta varios enfoques para modelar el polimorfismo. ¿ Y qué relación tiene el paquete django-polymorphic con todo esto ? Este paquete permite implementar de forma fácil, y de forma concreta, la herencia multi tabla. Si definimos los siguientes modelos para un `Proyecto` : ```python from polymorphic.models import PolymorphicModel class Proyecto(PolymorphicModel): tema = models.CharField(max_length=30) class ProyectoArte(Proyecto): artista = models.CharField(max_length=30) class ProyectoInvestigacion(Proyecto): supervisor = models.CharField(max_length=30) ``` Y luego creamos algunos proyectos ```python >>> Proyecto.objects.create(topic="Fiesta de Departamento") >>> ProyectoArte.objects.create(tema="Pintando con Tim", artista="T. Turner") >>> ProyectoInvestigacion.objects.create(tema="Aerodinamica", supervisor="Dr. Winter") ``` Al realizar la consulta de `Proyectos`, obtenemos los resultados con polimorfismo: ```python >>> Proyecto.objects.all() [ <Proyecto: id 1, tema "Fiesta de Departamento">, <ArtProject: id 2, tema "Pintando con Tim", artista "T. Turner">, <ProjectoInvestigacion: id 3, tema "Aerodinamica", supervisor "Dr. Winter"> ] ``` ## 2 [django-allauth](https://www.intenct.nl/projects/django-allauth/) django-allauth provee un conjunto de aplicaciones modulares integradas que implementan los flujos comunes de registro y login, tanto locales como integrados con redes sociales. Se destaca especialmente al soportar de forma simultánea los flujos para login local y con redes social. It just works™. ## 3 [Django Lifecycle Hooks](https://rsinger86.github.io/django-lifecycle/) Este paquete es mi nuevo favorito. Aún se encuentra en beta así que no lo recomendaría de entrada para uso en producción. Sin embargo, creo que tiene el potencial de mejorar la claridad del código y el mantenimiento de [modelos gordos](https://django-best-practices.readthedocs.io/en/latest/applications.html). Puede reemplazar las [Signals](https://docs.djangoproject.com/en/dev/ref/signals/) y los hooks `__init__` & `save`. Por ejemplo, si está acostumbrado a hacer lo siguiente con hooks: ```python class Article(LifecycleModel): contents = models.TextField() updated_at = models.DateTimeField(null=True) status = models.ChoiceField(choices=['draft', 'published']) editor = models.ForeignKey(AuthUser) def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self._orig_contents = self.contents self._orig_status = self.status def save(self, *args, **kwargs): if self.pk is not None and self.contents != self._orig_contents): self.updated_at = timezone.now() super().save(*args, **kwargs) if self.status != self._orig_status: send_email(self.editor.email, "An article has published!") ``` Con este paquete lo podría hacer de esta forma: ```python from django_lifecycle import LifecycleModel, hook, BEFORE_UPDATE, AFTER_UPDATE class Article(LifecycleModel): contents = models.TextField() updated_at = models.DateTimeField(null=True) status = models.ChoiceField(choices=['draft', 'published']) editor = models.ForeignKey(AuthUser) @hook(BEFORE_UPDATE, when='contents', has_changed=True) def on_content_change(self): self.updated_at = timezone.now() @hook(AFTER_UPDATE, when="status", was="draft", is_now="published") def on_publish(self): send_email(self.editor.email, "An article has published!") ``` Los hooks también pueden referirse a cambios en campos de objetos relacionados (con foreign keys). Lo repito, es importante notar que este paquete se encuentra en beta y por tanto es importante examinarlo de forma detallada viendo el código que genera. ## 4 [Django Extensions](https://github.com/django-extensions/django-extensions) Django Extensions es uno de los paquetes útiles más antiguos que conozco, algo así como desde el año 2008. Este paquete merece un artículo por si solo pero estas son algunas de las características que uso: ### shell_plus `./manage.py shell_plus` lanza un shell de Django con toos los modelos importados y listos para usar. Me gusta combinarlo con IPython para mejorar la experiencia con auto completado. ### RunScript Algunas veces queremos correr un script en nuestra aplicación de Django, un flujo de trabajo típico es usar el shell de django y luego convertir esto en un script. Este comando nos permite correr una función simple como si estuvieramos en un shell de django. Por ejemplo, si quisieramos un script para borrar todos los objectos de tipo `Question` de la base datos lo podríamos hacer con este paquete de forma tan simple como: ```python # scripts/delete_all_questions.py from polls.models import Question def run(): # Fetch all questions questions = Question.objects.all() # Delete questions questions.delete() ``` Y lueg correr el script: ``` ./manage.py manage.py runscript delete_all_questions ``` ### syncdata syncdata resetea la base de datos de tal forma que solo contenga exactamente las fixtures especificadas en el archivo de fixtures. ### graph_models Este comando permite visualizar los modelos de la aplicación django permitiendo ver las [relaciones](https://en.wikipedia.org/wiki/Relation_(database)) de forma similar a un diagrama [entidad-relación]((https://en.wikipedia.org/wiki/Entity%E2%80%93relationship_model)) ![entity-relationship diagram](https://docs.monadical.com/uploads/upload_77f772290b99de48fe5d20418345ec5c.png) ## 5 [Cookiecutter Django](https://github.com/pydanny/cookiecutter-django) Si alguna vez ha arrancado un proyecto de Django debe saber que el comando`django-admin startproject mysite` no es suficiente para tener todas las características de una aplicación web moderna. Por ejemplo, variables de entorno para la configuración, integración con Postgres, docker(-compose), etc. Django Cookiecutter se encarga de esto por usted. Recomiendo usarlo *después* de familiarizarse con cada componente por separado. De otra forma, la "magia" y las configuraciones dificultarán la depuración en el futuro así como también puede llevar a tener código muerto si no se entiende qué está haciendo cada cosa. --- <center> <img src="https://monadical.com/static/logo-black.png" style="height: 80px"/><br/> Monadical.com | Full-Stack Consultancy *We build software that outlasts us* </center>



Recent posts:


Back to top