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

983
Vistas
Django: anotar múltiples campos de una subconsulta

Estoy trabajando en un proyecto de Django en el que tengo un conjunto de consultas de objetos 'A' ( A.objects.all() ), y necesito anotar varios campos de una subconsulta de objetos 'B'. El problema es que el método de anotación solo puede manejar un tipo de campo por parámetro (DecimalField, CharField, etc.), por lo tanto, para anotar múltiples campos, debo usar algo como:

 A.objects.all().annotate(b_id =Subquery(B_queryset.values('id')[:1], b_name =Subquery(B_queryset.values('name')[:1], b_other_field =Subquery(B_queryset.values('other_field')[:1], ... )

Lo cual es muy ineficiente, ya que crea una nueva subconsulta/subselección en el SQL final para cada campo que quiero anotar. Me gustaría usar la misma subselección con varios campos en sus parámetros de valores (), y anotarlos todos en el conjunto de consultas de A. Me gustaría usar algo como esto:

 b_subquery = Subquery(B_queryset.values('id', 'name', 'other_field', ...)[:1]) A.objects.all().annotate(b=b_subquery)

Pero cuando trato de hacer eso (y accedo al primer elemento A.objects.all().annotate(b=b_subquery)[0] ) genera una excepción:

{FieldError}Expression contains mixed types. You must set output_field.

Y si configuro Subquery(B_quer...[:1], output_field=ForeignKey(B, models.DO_NOTHING)) , obtengo una excepción de base de datos:

{ProgrammingError}subquery must return only one column

En pocas palabras, todo el problema es que tengo varias B que "pertenecen" a una A, por lo que necesito usar Subquery para, por cada A en A.objects.all() , elegir una B específica y adjuntarla a esa A, usando OuterRefs y algunos filtros (solo quiero algunos campos de B), lo que me parece un problema trivial.

¡Gracias por cualquier ayuda de antemano!

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

0

Lo que hago en tales situaciones es usar prefetch-related

 a_qs = A.objects.all().prefetch_related( models.Prefetch('b_set', # NOTE: no need to filter with OuterRef (it wont work anyway) # Django automatically filter and matches B objects to A queryset=B_queryset, to_attr='b_records' ) )

Ahora a.b_records será una lista que contiene a's objetos b relacionados con a. Dependiendo de cómo filtre su B_queryset esta lista puede estar limitada a solo 1 objeto.

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