Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

205
Views
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 answers
Answer question

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 Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!