¿Qué es __(doble guion bajo)?

En Django, __(doble guion bajo) se utiliza cuando se escriben consultas de base de datos a través de campos relacionales entre modelos. En resumen, se usa para acceder a campos conectados a otras tablas o para filtrar datos que cumplen con ciertas condiciones.

Por ejemplo, cuando dos o más modelos están conectados a través de relaciones como ForeignKey o OneToOneField, se pueden acceder a los campos deseados a través de esa relación. Aquí, __ actúa como una especie de "eslabón" que permite encadenar y acceder a campos de diferentes modelos.

Ejemplo: Uso de __ en relaciones entre modelos

Pongamos un ejemplo sencillo. Supongamos que el modelo Profile está conectado al modelo User, y que este último tiene un campo llamado username. Podemos filtrar perfiles específicos en base al username del User.

Definición del modelo:

from django.db import models
from django.contrib.auth.models import AbstractUser

class CustomUser(AbstractUser):
    pass

class Profile(models.Model):
    user = models.OneToOneField(CustomUser, on_delete=models.CASCADE)
    bio = models.TextField()

En el ejemplo anterior, el modelo Profile tiene una relación uno a uno con CustomUser. Ahora veamos cómo acceder al campo de CustomUser desde Profile utilizando __.

Consulta usando __:

# Filtrando objetos Profile basado en el username de CustomUser
profiles = Profile.objects.filter(user__username='jesse')

Aquí, user__username es la clave. user es el campo vinculado al CustomUser dentro del modelo Profile, y para acceder al username de ese campo, simplemente lo conectamos con __. Esto nos permite obtener datos del campo username de CustomUser a partir del modelo Profile.

Diversas aplicaciones de __

El __ no solo se usa para acceder a campos, sino que también se emplea frecuentemente para establecer condiciones. Django ofrece varias funcionalidades de filtrado que permiten establecer diversas condiciones en los querysets, y la mayoría se implementan a través de __. Algunas de las condiciones más utilizadas son:

  • exact: Busca valores que coinciden exactamente. (Puede omitirse ya que es el valor predeterminado)
  • icontains: Busca valores que contengan lo especificado sin distinguir mayúsculas de minúsculas.
  • gt, lt, gte, lte: Condiciones para buscar valores mayores o menores (greater than, less than).
  • startswith, endswith: Busca valores que comiencen o terminen con una cadena específica.

Ejemplo: Diversas condiciones de filtro

# Consulta de todos los perfiles de CustomUser cuyo email contiene 'gmail.com'
profiles_with_gmail = Profile.objects.filter(user__email__icontains='gmail.com')

# Consulta de perfiles de CustomUser con ID mayor a 10
profiles_with_id_gt_10 = Profile.objects.filter(user__id__gt=10)

# Consulta de perfiles de CustomUser cuyo username comienza con 'jesse'
profiles_starting_with_jesse = Profile.objects.filter(user__username__startswith='jesse')

Acceso a campos de múltiples relaciones a través de __

Una de las características más poderosas de Django es la capacidad de seguir múltiples relaciones a través de __ para consultar datos, incluso cuando se conectan varios modelos. Por ejemplo, consideremos una situación en la que un modelo Order está conectado a Profile, y este a su vez está conectado a CustomUser.

Ejemplo de modelo con múltiples relaciones:

class Order(models.Model):
    profile = models.ForeignKey(Profile, on_delete=models.CASCADE)
    order_date = models.DateTimeField()
    amount = models.DecimalField(max_digits=10, decimal_places=2)

Ahora supongamos que queremos consultar los datos de Order basándonos en el username de CustomUser.

Filtrado de múltiples relaciones:

# Consultar pedidos en Order donde el username de CustomUser es 'jesse'
orders_for_user = Order.objects.filter(profile__user__username='jesse')

Aquí, podemos acceder al campo username de CustomUser a lo largo de varias etapas de relación usando profile__user__username. Esto implementa un filtrado sencillo aprovechando la relación entre OrderProfileCustomUser mediante __.

Resumen

  • __ se utiliza para referirse a campos a través de relaciones entre modelos.
  • Se pueden establecer diversas condiciones de consulta para filtrar datos.
  • Se pueden conectar campos de múltiples relaciones para manejar consultas complejas de manera sencilla.

Ahora que has comprendido el rol y la utilización de __, podrás escribir consultas más potentes en Django ORM. Si piensas en la estructura relacional de la base de datos y utilizas este símbolo adecuadamente, podrás manejar el procesamiento de datos de manera eficiente y lidiar con relaciones complejas de forma sencilla.