Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

197
Vistas
Prefetch personalizado de Django y anotación condicional

Estoy usando un objeto de captación previa personalizado para obtener solo algunos objetos relacionados, por ejemplo:

 unreleased_prefetch = Prefetch("chants", Chant.objects.with_audio()) teams = Team.objects.public().prefetch_related(unreleased_prefetch)

Esto funciona bien, pero también quiero saber el número de estos objetos y filtrarlos. Estoy feliz de poder usar queryset en este momento como parámetro para el objeto Prefetch (ya que uso mucho QuerySets/Managers personalizados).

¿Hay alguna forma de reutilizar esta consulta, que pase al objeto Prefetch de la misma manera con la anotación condicional?

Hasta ahora, mi anotación condicional es bastante fea y se ve así (hace lo mismo que mi canto original con consulta/filtro personalizado with_audio ):

 .annotate( unreleased_count=Count(Case( When(chants__has_audio_versions=True, chants__has_audio=True, chants__flag_reject=False, chants__active=False, then=1), output_field=IntegerField())) ).filter(unreleased_count__gt=0)

Funciona, pero es bastante feo y tiene lógica duplicada. ¿Hay alguna forma de pasar queryset a When de la misma manera que puedo pasarlo a prefetch para evitar duplicaciones?

over 4 years ago · Santiago Trujillo
1 Respuestas
Responde la pregunta

0

No digo que esta sea la mejor práctica ni nada, pero quería proporcionar una forma potencial de lidiar con tal situación.

Digamos que tiene una clase ChantQuerySet :

 class ChantQuerySet(models.QuerySet): def with_audio(self): return self.filter(chants__has_audio_versions=True, chants__has_audio=True, chants__flag_reject=False, chants__active=False)

Lo que usa como gerente haciendo algo como lo siguiente, probablemente:

 class Chant(models.Model): # ... objects = ChantQuerySet.as_manager()

Sugeriría almacenar el filtro en el QuerySet :

 from django.db.models import Q class ChantQuerySet(models.QuerySet): @property def with_audio_filter(self): return Q(chants__has_audio_versions=True, chants__has_audio=True, chants__flag_reject=False, chants__active=False) def with_audio(self): return self.filter(self.with_audio_filter)

Esto le da la capacidad de hacer esto:

 Chant.objects.annotate( unreleased_count=Count(Case( When(ChantQuerySet.with_audio_filter, then=1), output_field=IntegerField())) ).filter(unreleased_count__gt=0)

Ahora puede cambiar el filtro solo en un lugar, si necesita hacerlo, sin tener que cambiarlo en todas partes. Para mí, tiene sentido almacenar este filtro en QuerySet y, personalmente, no veo nada de malo en eso, pero solo soy yo.

Sin embargo, una cosa que cambiaría es hacer que la propiedad with_audio_filter se almacene en caché o almacenarla en un campo en el constructor al inicializar ChantQuerySet .

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda