Django сумма, основанная на отношениях с иностранными ключами (задействовано 3 модели) - PullRequest
1 голос
/ 06 февраля 2020

У меня следующий вопрос: у меня есть 3 модели: Contrato, Movimiento и MovimientoDato, мне нужно сгенерировать набор запросов, который отбрасывает мне сумму поля importe MovimientoDato для каждого Contrato, MovimientoDato связан с Movimiento, а Movimiento связан Contrato через внешние ключи В результирующем наборе запросов мне нужны все поля Contrato плюс поле, которое мы можем назвать сальдо, которое складывает суммы MovimientoDato.importe, связанных с каждым контрактом, используя Movimiento в качестве моста для создания SUM Group, возможно ли это?

Вот модели:

class Movimiento(models.Model):
    fecha = models.DateField(default=timezone.now)
    contrato = models.ForeignKey(Contrato, related_name='rn_contratos',
    on_delete=models.CASCADE)
    OPCIONES = (
        (1, 'Abono'),
        (2, 'Cargo'),
    )
    tipomovimiento = models.IntegerField(choices=OPCIONES, default=1)
    formapago = models.ForeignKey(
        FormaPago, on_delete=models.CASCADE, null=True, blank=True)
    nota = models.CharField(max_length=255, blank=True)
    archivo = models.FileField(upload_to='images/', blank=True)
    user = models.ForeignKey(User, on_delete=models.CASCADE)

class MovimientoDato(models.Model):
    movimiento = models.ForeignKey(
    Movimiento, related_name='partidas', on_delete=models.CASCADE)
    categoria = models.ForeignKey(Categoria, on_delete=models.CASCADE)
    concepto = models.CharField(max_length=150, verbose_name="Concepto")
    importe = models.DecimalField(max_digits=12, decimal_places=2, default=0)

class Contrato(models.Model):
    propiedad = models.ForeignKey(Propiedad, on_delete=models.CASCADE)
    inquilino = models.ForeignKey(Inquilino, on_delete=models.CASCADE)
    fechainicio = models.DateField(default=datetime.now)
    fechafinal = models.DateField(default=datetime.now)
    renta_check = models.BooleanField(default=True)
    renta = models.DecimalField(max_digits=15, decimal_places=2, default=0)
    mantenimiento_check = models.BooleanField(default=True)
    mantenimiento = models.DecimalField(
        max_digits=15, decimal_places=2, default=0)
    agua_check = models.BooleanField(default=True)
    agua = models.DecimalField(max_digits=15, decimal_places=2, default=0)
    electricidad_check = models.BooleanField(default=True)
    electricidad = models.DecimalField(
        max_digits=15, decimal_places=2, default=0)
    deposito = models.DecimalField(max_digits=15, decimal_places=2, default=0)
    status = models.BooleanField(default=True)
    user = models.ForeignKey(User, on_delete=models.CASCADE)

Я искал, как это сделать с помощью itertools, Q (), F (), но я не могу заставить его работать

Большое спасибо

1 Ответ

1 голос
/ 06 февраля 2020

Да , вы можете .annotate(..) [Django -doc] Contrato набор запросов с:

from django.db.models import <b>Sum</b>

Contrato.objects.annotate(
    <b>balance=Sum('rn_contratos__partidas__importe')</b>
)

Contrato объекты, которые возникают из этого набора запросов, будут иметь дополнительный атрибут .balance, который является суммой .importe s всех связанных MovimientoDato (через модель Movimiento).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...