Consultas Django – usando todo

Usando varios elementos de las consultas para hacer una consulta compleja

qs = Person.objects.annotate(birth_year_int=Cast(
    ExtractYear("birthdate"),
    output_field=IntegerField(),),
    birth_year_modulus_4=F("bith_year_int") % 4,
    birth_year_modulus_100=F("birth_year_int") % 100,
    birth_year_modulus_400=F("birth_year_int") % 400,
).annotate(born_in_leap_year=Case(
    When(Q(Q(birth_year_modulus_4=0) & 
        Q(~Q(birth_year_modulus_100=0) | Q(birth_year_modulus_400=0))
    ),then=True,),
    default=False,
    output_field=BooleanField(),
).filter(born_in_leap_year=True)
.values_list("birthdate__date", flat=True)
)

for year in years:
   assert calendar.isleap(year), (f"{year} ins't a leap year")
     

Extraído de

DjangoCon 2019 – Building effective Django queries with expressions by Vanessa Barreiros – YouTube

Consultas Django Conditionals

class Order(models.Model):
    created_at = models.DateTimeField(auto_now_add=True)
    customer = models.ForeignKey(Person, related_name="orders",on_delete=models.CASCADE)
    total = models.PositiveIntegerField()

aplicando un descuento a los clientes antiguos

from django.utils import timezone

orders = Order.bjects.filter(created_at__date=timezone.now().date()

for order in orders():
    customer_joined_year = order.customer.joined_on.year
    if(customer_joined_year >= 2010 and customer_joined_year <2019):
        order.total *=0.8
        order.save()
    elif(customer_joined_year <= 2000 and cutomer_joined_year >= 1995):
        order.total *= 0.6
        order.save()

ahora la versión con Conditionals

from django.db.models import Case, When

orders.annotate(discounted_total=
    Case(
        When(customer__joined_on__year__range=(1995, 2018),
            then=F("total") * 0.8,), 
        When(customer__joined_on__year__range=(1995, 2000),
            then=F("total") * 0.6,),
        default="total",)
)
      

Extraído de

DjangoCon 2019 – Building effective Django queries with expressions by Vanessa Barreiros – YouTube

Consultas Django Coalesce

No se bien su uso

from django.db.models.functions import Coalesce, NullIf
class Person(models.Model):
    first_name = models.Charfield(max_length=255)
    nickname = models.Charfield(max_length=255, null=True, blank=True)
    ...
Person.objects.annotate(
    goes_by=Coalesce("nickname", "first_name")
).values_list("goes_by")

None si la cadena es vacía «»

Person.objects.annotate(
    goes_by=Coalesce(
        NullIf("nickname", Value(""))
        "first_name"
    )
).values_list("goes_by")