Django ORM: La classe F
En els propers apunts vull parlar de l'ORM de Django. Crec que més o manco tothom coneix la manera de fer consultes per clau primària o fer un filtre, crear un objecte i guardar-lo en la base de dades i les operacions més comuns.
El que m'agradaria és començar a tractar aquestes funcions potser menys conegudes però tremendament útils en el dia a dia, que poden fer el nostre codi més robust i ràpid.
Una d'aquests funcionalitat és la class F. Aquesta classe ens permetrà accedir directament als camps del model des de la base de dades, és a dir, utilitza el nom del camp per montar la consulta SQL i executar-la dins la base de dades enlloc de requerir una consulta per l'obtenció del valor i una altra per l'execució.
La classe F fa que el nostre codi sigui més ràpid, ja que requereix menys accessos a la base de dades i a més evita algunes race conditions que es poden donar en el temps d'agafar i actualitzar un valor de la base de dades. Vegem-ne alguns exemples típics:
Actualitzador d'un comptador
Suposem que tenim un model amb un camp que anomenarem acumulador
, cada vegada que l'usuari accedeix a l'objecte volem incrementar aquest acumulador
# mètode clàssic
obj = Model.objects.get(pk=valor) obj.acumulador += 1 obj.save()
# fent servir la classe F
from django.db.models import F Model.objects.filter(pk=valor).update(F('acumulador')+1)
En el primer cas hem d'obtenir primer el valor, posar-ho en memòria i fer-ne l'increment per a després guardar-lo.
En el segon cas, quan fem servir F('acumulador')
el que estam dient a l'ORM de Django és que agafi el valor del camp i l'actualitzi en el mateix moment d'executar la sentència SQL
Fer referència al valor d'un camp a una consulta
L'altra cas típic és el que necessitam fer algun tipus de consulta basat en el valor que té el camp del nostre objecte.
Entry.objects.filter(rating__lt=F('n_comments') + F('n_pingbacks'))
Aquest exemple està agafat de la documentació de Django. Com podeu veure fem servir F()
per obtenir els valors dels camps n_comments
i n_pingbacks
i sumar-los abans de fer la consulta.
En definitiva, la classe F()
es pot fer servir sempre que necessitem fer referència a un camp del nostre objecte. Estalviant-nos consultes innecessàries i simplificant el nostre codi.
No deixeu de consultar al documentació a la documentació sobre expressions de Django.