【问题标题】:Looking for a better OOP approach寻找更好的 OOP 方法
【发布时间】:2013-05-07 09:42:04
【问题描述】:

我想更新用户余额。为此,目前我必须保存 Account 对象,请考虑以下视图:

def refresh_balance(request):
    """
    Balance Refresh.

    The balance shown on every page is a cached balance for performance reasons.
    To get the real balance you need to re-save the account object which will refresh
    the cached value in the database.

    """
    page = request.GET['redirect']
    account = Account.objects.get(user=request.user)
    account.save()
    message_user(
        request.user,
        "Account Balance Refreshed.")
    return HttpResponseRedirect(page)

在 model.py 中,我有以下 类方法 来做腿部工作:

def save(self, *args, **kwargs):
        self.balance = self._balance()
        return super(Account, self).save(*args, **kwargs)


    def _balance(self):
        aggregates = self.transactions.aggregate(sum=Sum('amount'))
        sum = aggregates['sum']
        return D('0.00') if sum is None else sum

这对我来说看起来很麻烦,我正在重新保存以重新保存(如果这有意义的话),理想情况下,我只想在我的任何视图中调用 refresh(),只要我想。我不是 Django 专家,需要一些关于如何更好地处理这个问题的建议。

我看过静态方法可能吗?

def _balance(self):
        aggregates = self.transactions.aggregate(sum=Sum('amount'))
        sum = aggregates['sum']
        return D('0.00') if sum is None else sum

    @staticmethod
    def update_balance(model):
        model.balance = unsure here as I need 'self'? 

那就直接打电话Account.update_balance(Account)?????

有什么建议吗? PS这不是一个悬而未决的问题,很清楚我正在尝试做什么以及我在追求什么。谢谢:)

【问题讨论】:

  • 为什么不在 Account 模型中创建 refresh 对象方法(不是静态的),它会执行所需的操作,然后从这个 refresh 方法调用 self.save()?
  • 听起来像是你可以在数据库上使用存储过程来做的事情。
  • @Aya 存储过程会很好,但我现在正在代码中寻找一种方法,我不想在这个阶段将自己锁定在数据库中。
  • 为什么不使用信号仅在创建交易时重新计算余额? (我假设事务只能创建 - 永远不会更新或删除,但即便如此你也可以使用信号)
  • @brunodesthuilliers:这可能行得通,但在添加许多事务时也会产生很多问题。我宁愿添加一个信号,仅在添加交易时清除余额,并在获取时计算它(如果清除)。但我没有那个代码。 :-)

标签: python django


【解决方案1】:

Stalk 的答案很好,但是当方法只做一件事且只做一件事时,我更喜欢它。 就像现在一样,.refresh() 负责两件事。计算余额和储蓄。 我会通过实现.refresh() 方法来进一步分解它,但在视图中这样做。 (我也将其命名为 refresh_balance 而不是 refresh,refresh 意味着我们刷新整个帐户)。

account.refresh_balance()
account.save()

这使得.refresh_balance() 的逻辑可以改变,但.save() 将独自做最好的事情。将模型保存到数据库中。

这也将使您的代码不易出错。 我们还将遵循 Python 之禅:“显式胜于隐式”。

【讨论】:

  • 我喜欢这个答案,是的,这是一个让它们像这样分开的好方法。
【解决方案2】:

很容易创建自定义模型方法,例如refresh:

class Account(models.Model):
    # ... some fields

    def refresh(self):
        # do needed stuff
        self.balance = self._balance()
        self.save()

然后直接调用它:

# ...
account = Account.objects.get(user=request.user)
account.refresh()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-08-11
    • 2014-05-04
    • 2015-11-24
    • 1970-01-01
    • 1970-01-01
    • 2014-07-20
    • 1970-01-01
    相关资源
    最近更新 更多