El Blog de Trespams

Blog personal sobre tecnologia, gestió de projectes i coses que se me passen pel cap

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.

blog comments powered by Disqus