10 pacchetti per Django

by Giovanni Fumagalli e Mauro Bianchi - 08/10/2020
Python
Django

In questo articolo vi suggeriamo 10 pacchetti software integrabili con Django che aiutano a risolvere alcune delle problematiche più ricorrenti nello sviluppo di applicativi web con questo framework.

1. Django REST framework

Categoria: sviluppo API

Link ↗️

Partiamo con Django REST framework, il pacchetto di riferimento per realizzazione di API REST con Django.

Grazie ai suoi concetti di viewsets e serializers permette di realizzare CRUD con poche linee di codice, mantenendo comunque una grande flessibilità, grazie a un'API semplice ed elegante e a una documentazione impeccabile. Vi invitiamo a leggere il codice sorgente del repository, chiaro e immediato anche per chi non ha familiarità con la codebase.

Infine, proprio come Django, REST framework ha a sua volta un ricco ecosistema di pacchetti aggiuntivi che permettono di integrare facilmente gli aspetti fondamentali delle REST API, come autenticazione, paginazione e filtri.

🗒️ Nota Se vi piace il design di REST framework, date un'occhiata anche a django-vanilla-views, un altro pacchetto di Tom Christie, il creatore di rest framework, che rende disponibili delle classi alternative alle class based views di Django, con un'API semplificata. Il suo utilizzo non è imprescindibile, visto che Django fornisce le stesse funzionalità con un'API diversa, ma è un esempio di libreria molto ben progettata e pensata per semplificare lo sviluppo con Django.

2. drf-spectacular

Categoria: sviluppo API, documentazione

Link ↗️

Rimanendo in tema REST framework, drf-spectacular permette la creazione di uno schema OpenAPI 3.0 a partire dalle vostre API implementate tramite REST framework senza nessuna configurazione. Questo pacchetto, inoltre, permette allo stesso modo di generare automaticamente un client swagger e un sito di documentazione redoc.

3. Django-RQ

Categoria: job asincroni

Link ↗️

Implementare un sistema di code di job asincroni basato su Redis è un task che può risultare all'apparenza semplice, ma è proprio nei dettagli che nasconde le sue difficoltà (priorità, concorrenza, gestione job falliti). Grazie a Django-RQ non dovrete più pensare a niente. Infatti, questo pacchetto, sviluppato dagli stessi creatori di RQ, implementa rapidamente un sistema di code perfettamente funzionante. In aggiunta, Django-RQ fornisce una comodissima interfaccia admin in cui potrete vedere lo stato della coda ed eventualmente rimettere in coda o eliminare i job falliti. Queste stesse informazioni sono disponibili anche tramite JSON.

💡 Consiglio: RQ, multiprocessing e scrittura dei job asincroni

Quando lavorate con RQ cercate di non tenere persistenza o connessioni aperte tra i job, quindi evitate i singleton a livello app in Django e piuttosto istanziate tutto all'interno del job stesso. Nella versione attuale, se usate Python requests all'interno del worker potreste incorrere in crash su MAC OSX ... Questa variabile d'ambiente vi risparmierà ore di mal di testa:

export OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES

Vedi anche questo post su stack overflow

4. Django-storages

Categoria: storage e serving di files

Link ↗️

Questo pacchetto fornisce dei backend Django storage per i principali servizi di cloud storage tra cui Amazon S3, Apache Libcloud, Azure Storage, Digital Ocean, Dropbox, FTP, Google Cloud Storage e SFTP. Nella documentazione potete trovare le configurazioni specifiche per il servizio da voi scelto.

Spostare i media su un servizio cloud vi mette al riparo da problemi, quali backup e spazio insufficiente su disco, e inoltre è un requisito fondamentale per la scalabilità in ambito microservices.

Per quanto riguarda i file statici spostare gli stessi su un servizio di cloud, magari con funzionalità specifiche di cdn distribuito, alleggerisce il carico del vostro webserver sia a livello di banda che di computazione.

💡 Consiglio: gestione di files statici vs media uploads su Amazon S3

Django-storages permette di configurare facilmente Amazon S3 (o uno storage con la stessa API come "Spaces" di Digital Ocean), che richiede configurazioni leggermente diverse per i file statici e i media, ovvero gli upload da parte degli utenti. Per gestire correttamente i permessi sui file (pubblici i file statici e autenticati i media) attraverso le acl di S3 è possibile creare una sottoclasse ad hoc del backend S3StaticStorage fornito dal pacchetto per modificarne la configurazione. Un esempio di implementazione di una classe di storage per i file statici su S3 può essere la seguente:

from storages.backends.s3boto3 import S3StaticStorage

class MyWebSiteS3StaticStorage(S3StaticStorage):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.default_acl = 'public-read'

Rimandiamo alla documentazione per tutti i dettagli.

5. Django-push-notifications

Categoria: push notifications per app mobile

Link ↗️

Questo pacchetto astrae e semplifica la gestione lato server delle push notifications, una funzionalità richiesta in molte app mobile per l'invio ai due servizi Apple (APN) e Android (GCM).

Il pacchetto offre due comodi modelli Django APNSDevice e GCMDevice entrabi con una ForeignKey al modello utente e un metodo send_message sul queryset per inviare messaggi. L'implemetazione garantisce che chiamando il metodo sul queryset i messaggi siano spediti in bulk.

from push_notifications.models import APNSDevice, GCMDevice

devices = GCMDevice.objects.filter(user__first_name="Giovanni")
devices.send_message("Ciao a tutti i Giovanni del mondo!")

In aggiunta, Django-push-notifications offre un'integrazione con il sopra citato Django REST framework, in modo da avere a disposizione delle comode API per gestire i device dell'utente e aggiornare i registration token degli stessi. Questa è una funzionalità fondamentale se state sviluppando un'App nativa nella quale volete mandare dei messaggi a un account utente dopo un login effettuato nella vostra App.

Infine, la libreria fornisce anche un'integrazione in Django admin che permette di mandare direttamente un messaggio di test, funzionalità molto utile in fase di debug.

6. Django-colorfield

Categoria: modello dati

Link ↗️

Il nome di questo pacchetto è abbastanza autoesplicativo: se un campo dei vostri modelli dati è un colore questo è il pacchetto che fa per voi!

Oltre a validare il formato del campo come hex o hexa fornisce un comodo color picker come widget del vostro campo all'interno di Django admin.

7. Django-extensions (graph models)

Categoria: modello dati, documentazione

Link ↗️

Il pacchetto django-extensions contiene molte funzionalità aggiuntive al framework Django. In questo caso parleremo solo del comando che permette la generazione dello schema relazionale del database. Questa funzionalità di django-extensions è particolarmente utile in quanto permette di generare lo schema del nostro modello dati rapidamente e senza alcuna configurazione.

Vediamo ora come generare lo schema in pochi passi.

Installa il pacchetto:

pip install django-extensions pygraphviz

Aggiungilo tra le INSTALLED_APPS dei settings del progetto Django per abilitare i comandi di management:

INSTALLED_APPS = [
  'django_extensions',
]

E utilizza il comando graph_models per generare lo schema:

python manage.py graph_models -a -g -o schema_db.png

Et voilà ecco un'immagine con lo schema del database!

8. Django-anymail

Categoria: invio email

Link ↗️

Questo pacchetto fornisce degli email backend per i maggiori fornitori di servizi di email in cloud tra cui: Amazon SES, Mailgun, Mailjet, Mandrill, Postal, Postmark, SendGrid, Sendinblue e SparkPost.

Il grande vantaggio di utilizzare uno di questi servizi accoppiato a questo pacchetto è che la funzione send_email di Django o similari non passerà più da SMTP bensì invierà le email tramite API. Cosa comporta questo? La maggior parte di questi servizi di mail implementa già al suo interno un sistema di code, questo comporta che la chiamata a send_email non vi farà più aspettare tempi biblici, ma sarà quasi instatanea, visto che sarà il vostro servizio a mettere in coda email e spedirla in un secondo momento. In questo modo non sarà praticamente più necessario spostare la logica di invio email in una coda nel vostro applicativo o utilizzare soluzioni equivalenti come celery o lo stesso rq di cui abbiamo già parlato, ma potrete benissimo mettere la chiamata a send_email nella vostra view senza preoccuparvi che questa diventi troppo lenta.

Infine, se il vostro applicativo ha bisogno di tracciamento dei click django-anymail supporta queste funzioni avanzate specifiche per ogni singolo backend.

9. FactoryBoy

Categoria: testing

Link ↗️

Questo pacchetto permette la generazione di dati casuali o pseudo casuali, ed è utile per generare dati di test in modo automatico.

Basato sulla famosa libreria Faker questo pacchetto offre una comoda integrazione con Django. Bastano veramente poche righe per generare record casuali con i quali popolare il vostro database. Ecco un esempio di utilizzo sul modello utente di Django:

import factory
from django.contrib.auth import get_user_model

# Supponiamo di avere un modello utente con i campi: email e name
User = get_user_model()

class UserFactory(factory.django.DjangoModelFactory):
    email = factory.Faker('email')
    name = factory.Faker('name')
    class Meta:
        model = User

  # Crea 100 utenti random in batch
  UserFactory.create_batch(100)

10. WeasyPrint

Categoria: generazione pdf

Link ↗️

Concludiamo con un pacchetto che non è propriamente un pacchetto Django ma potrà aiutarvi a risolvere un task molto comune durante lo sviluppo di applicativi web: generare pdf in modo dinamico.

WeasyPrint converte il vostro html in un file pdf e supporta funzioni avanzate come la generazione del numero pagina nel piè di pagina del vostro pdf. Combinando questa funzione con il motore di template di Django generare pdf dinamici diventa veramente semplice, qui sotto un codice di esempio:

from django.http import FileResponse
from django.template.loader import render_to_string
from tempfile import TemporaryFile
from weasyprint import HTML

def my_pdf_view(request):
  # Renderizza il template di Django e ritorna la stringa html
  html = render_to_string('my_template_pdf.html')
  # Crea l'oggetto pdf dalla stringa html
  pdf = HTML(string=html)
  # Crea un file temporaneo
  fp = TemporaryFile()
  # Scrive il contenuto del pdf nel file temporano
  pdf.write_pdf(fp)
  # Sposta il puntatore del file all'inzio senza qesto si vedrebbe un pdf vuoto
  fp.seek(0)
  # Scelgo un nome per il file pdf
  filename = 'my_pdf_file_name.pdf'
  # Mando il file pdf come risposta
  response = FileResponse(fp, filename=filename, content_type="application/pdf")
  response["Content-Disposition"] = 'filename="%s"' % (filename,)
  return response

Note finali

Abbiamo elencato 10 librerie Python integrate con Django, che coprono una serie di problematiche e casi d'uso molto differenti. Quali sono i tuoi pacchetti Django preferiti? Siamo curiosi di ricevere vostri feedback e suggerimenti, Puoi trovarci su facebook e twitter. Se ti è piaciuto questo articolo faccelo sapere!