es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Obtener lista de campos de una relación inversa.

Estoy tratando de obtener la lista de recuentos de un campo basado en la fecha para poder graficar un gráfico de barras apiladas en el frontend. Estos son mis modelos:


class BaseModel(models.Model):
    id: int
    created_at = models.DateTimeField(verbose_name="Creado", auto_now_add=True)
    updated_at = models.DateTimeField(verbose_name="Última actualización", auto_now=True)

class Meta:
    abstract = True

class A(BaseModel):


name = models.CharField(max_length=512, null=True, blank=True)

class B(BaseModel):
a = models.ForeignKey(A, on_delete=models.CASCADE)

class C(BaseModel):
b = models.ForeignKey(B, on_delete=models.CASCADE)

Estoy tratando de obtener el recuento (como lista) de B y C al obtener la lista de A durante los últimos 7 días. Pero en cambio, estoy obteniendo el recuento en lugar de un objeto.

Utilizando recharts en el frontend, el formato de salida deseado será (utilizando datos de muestra de internet):


{
  "items": [
    {
      "name": "aplicación de Android",
      "chart_data": [
        {
          "name": "A",
          "x": 12,
          "y": 23,
          "z": 122
        },
        {
          "name": "B",
          "x": 22,
          "y": 3,
          "z": 73
        },
        {
          "name": "C",
          "x": 13,
          "y": 15,
          "z": 32
        }
      ]
    },
    {
      "name": "My",
      "chart_data": [
        {
          "name": "A",
          "x": 12,
          "y": 23,
          "z": 122
        },
        {
          "name": "B",
          "x": 22,
          "y": 3,
          "z": 73
        },
        {
          "name": "C",
          "x": 13,
          "y": 15,
          "z": 32
        }
      ]
    }
  ]
}
Tags:  , ,

Answer

  1. Avatar for davy.ai

    Para obtener la cantidad de B y C al obtener la lista de A de los últimos 7 días, puedes usar el ORM de Django para realizar agregación y filtrado.

    Primero, puedes filtrar los objetos BaseModel para incluir solo aquellos creados en los últimos 7 días usando la consulta __gte para el campo created_at. Luego, puedes usar las características de agregación de Django para agrupar los objetos B y C por sus claves foráneas a A y contarlos.

    Aquí tienes un ejemplo de consulta para obtener las cuentas de objetos B y C agrupados por sus respectivos objetos A creados en los últimos 7 días:

    from django.db.models import Count
    from django.utils import timezone
    
    ultima_semana = timezone.now() - timezone.timedelta(days=7)
    
    conteos_a = A.objects.filter(created_at__gte=ultima_semana).annotate(
        conteo_b=Count('b'),
        conteo_c=Count('b__c')
    ).values('id', 'nombre', 'conteo_b', 'conteo_c')
    

    Esto devolverá un conjunto de resultados con id, nombre, conteo_b y conteo_c para cada objeto A creado en los últimos 7 días. Luego puedes usar estos datos para formatearlos en el formato de salida deseado para tu frontend.

    Para formatear los datos en el formato de salida deseado, puedes recorrer el conjunto de resultados y crear una lista de diccionarios para cada objeto A con el nombre y los datos del gráfico (chart_data) que contengan los conteos de B y C.

    Aquí tienes un ejemplo de código para formatear los datos en el formato de salida deseado:

    salida = {'items': []}
    for a in conteos_a:
        salida['items'].append({
            'nombre': a['nombre'],
            'chart_data': [
                {'nombre': 'A', 'x': a['conteo_b'], 'y': a['conteo_c'], 'z': a['conteo_b'] + a['conteo_c']},
                {'nombre': 'B', 'x': a['conteo_b'], 'y': 0, 'z': a['conteo_b']},
                {'nombre': 'C', 'x': 0, 'y': a['conteo_c'], 'z': a['conteo_c']}
            ]
        })
    

    Esto creará un diccionario salida que contiene una lista de elementos con nombre y chart_data que puedes usar para representar el gráfico de barras apiladas en tu frontend usando recharts.

Comments are closed.