En este apunte vamos a hablar un poco de una característica poco conocida del ORM de Django. A estas alturas todo el mundo conoce cómo hacer consultas por clave primaria o un filtro o cómo crear un objeto y guardarlo en la base de datos.

La clase F es de estas características poco conocidas del ORM que lo hacen muy útil y potente en la vida diaria. Ayuda a que nuestro código sea más rápido, limitando el número de accesos que se hacen a la base de datos y además evita algunas race conditions que se pueden dar al estar utilizando un valor de la base de datos a partir de nuestro objeto Django. Veamos algunos ejemplos típicos:

Actualizar un contador

Supongamos que tenemos un modelo que contiene un campo al que llamaremos acumulador, cada vez que el usuario accede al objeto queremos incrementar este acumulador:

# método clásico
obj = Model.objects.get(pk=valor)
obj.acumulador += 1
obj.save()

# utilizando la clase F
from django.db.models import F
Model.objects.filter(pk=valor).update(F('acumulador')+1)

En el primer caso hemos de obtener primero el valor, guardarlo en la memoria y después proceder a incrementarlo y guardarlo.

En el segundo caso, utilizando F() estamos indicando al ORM de Django que obtenga el valor actual del campo y lo actualice dentro de la misma sentencia SQL.

Hacer referencia al valor de un campo en una consulta

Otro ejemplo típico es aquel en que necesitamos hacer algún tipo de consulta u operación basada en el valor que tiene un campo de nuestro objeto.

Entry.objects.filter(rating__lt=F('n_comments') + F('n_pingbacks'))

En este ejemplo, obtenido de la documentación de Django, utilizamos F() para obtener el valor de los campos n_comments y n_pingbacks y sumarlos antes de efectuar la consulta.

En definitiva, la clase F() se puede utilizar siempre que necesitemos referenciar un campo de nuestro objeto en consultas de filtrado u actualización, ahorrándonos consultas innecesarias y simplificando nuestro código.

blog comments powered by Disqus