【问题标题】:Django: how to create models that are computed from other models?Django:如何创建从其他模型计算的模型?
【发布时间】:2019-03-17 03:35:12
【问题描述】:

我有费用和收入模型。这两个模型应该是其他模型平衡的基础。

在哪里

balance.income = sum(incomes)
balance.expense = sum(expenses)
balance.rest = sum(incomes) - sum(expenses)

如何在 Django 中实现这种平衡模型?期望是,每当收入和支出模型从用户那里获得新数据时,余额将自动计算。下面是我对这些模型的实现,但是 Balance 模型需要修改(这里只是为了给出关于结构的想法)。

from django.db import models

class User(models.Model):
    user_id = models.AutoField(primary_key=True)
    firstname = models.CharField(max_length=20)
    lastname = models.CharField(max_length=20)

    def __str__(self):
        return self.firstname

class Balance(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    currency = models.CharField(max_length=3, default='$')
    income = models.IntegerField(default=0)
    expense = models.IntegerField(default=0)
    rest = models.IntegerField(default=0)
    saving = models.IntegerField(default=0)

    def __str__(self):
        return str(self.rest)

class Expense(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    date = models.DateField()
    category = models.TextField(default='')
    detail = models.TextField(default='')
    place = models.TextField(default='')
    amount = models.FloatField(default=0.0)

    def __str__(self):
        return self.detail

class Income(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    date = models.DateField()
    detail = models.TextField(default='')
    amount = models.FloatField(default=0.0)

    def __str__(self):
        return self.detail

【问题讨论】:

  • 您可以在两个模型中覆盖 save 方法或编写自定义 post_save 信号。

标签: django


【解决方案1】:

最简单的方法是重写.save() 方法。请注意,通过命令行保存模型时会绕过这一点。

class Balance(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    currency = models.CharField(max_length=3, default='$')
    income = models.IntegerField(default=0)
    expense = models.IntegerField(default=0)
    rest = models.IntegerField(default=0)
    saving = models.IntegerField(default=0)

    def __str__(self):
        return str(self.rest)

    def save(self, *args, **kwargs):
        user_incomes = Income.objects.filter(user=self.user).aggregate(Sum('amount'))['amount_sum']
        user_expenses = Expense.objects.filter(user=self.user).aggregate(Sum('amount'))['amount_sum']
        self.income = user_incomes
        self.expense = user_expenses
        self.balance = user_incomes - user_expenses
        super(Balance, self).save(*args, **kwargs)

【讨论】:

  • 我已经尝试过上面的解决方案,如果我在管理页面上更改余额数据然后保存,它会起作用。但是,当用户通过api调用添加支出和收入数据时,如何从浏览器脚本中访问余额保存方法?
  • 我不确定你的意思是什么,你能澄清一下吗?
猜你喜欢
  • 2012-08-21
  • 2018-05-05
  • 1970-01-01
  • 1970-01-01
  • 2023-04-09
  • 1970-01-01
  • 2021-11-14
  • 2021-09-25
  • 2016-06-28
相关资源
最近更新 更多