如何在模型方法中使用ValueError来避免模型管理器中的重复

时间:2017-03-18 20:09:47

标签: python django django-models exception-handling

我通过文档/示例来查看下面的代码。它有效,但我希望得到经验丰富的开发人员的一些帮助,因为这不是最有效的代码:

  • Checking_account.objects.get(user = request.user)使用2次(在模型管理器和视图中)
  • '没有足够的现金'检查执行2次(在模型管理器和视图中)

问题:是否可以使用模型方法中引发的“ValueError”作为触发器在模板中显示消息+指向“deposit_checkin_account_page”的链接(以这种方式避免模型管理器和视图中的重复或者是否应该以完全不同的方式解决这个问题?

欢迎所有建议!谢谢!

Models.py:

class Checking_accountManager(models.Manager):
    def check_balance(self, user, value):
        if Checking_account.objects.filter(user=user).exists():
            checking_account = Checking_account.objects.get(user=user)
            if value <= checking_account.current_balance:
                return True
        else:
            return False


class Checking_account(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    current_balance = models.DecimalField(_('Balans'), max_digits=18, decimal_places=8, default=0)

    objects = Checking_accountManager()

    def deposit(self, value):
        self.current_balance += value
        self.save()

    def withdraw(self, value):
        if value > self.current_balance:
            raise ValueError('not enough cash')
        self.current_balance -= value
        self.save()

Views.py:

view buy (request, item):
    item = item.objects.get(item=item)
    cost = item.cost

    if Checking_account.objects.check_balance(user=request.user, value=quote_cost):
        checking_account = Checking_account.objects.get(user=request.user)
        checking_account.withdraw(cost)
        messages.success(request, _('Succes.'))
    else:
        messages.error(request, _('no checking account yet or not enough cash.'))
        return HttpResponseRedirect(‘<deposit_checkin_account_page>’)
    return render(request, ‘buy.html')

编辑 - 2017年3月19日

基于回答Daniel Roseman,我已将代码更改为以下内容:

models.py 删除模型管理器

views.py

try:
    request.user.checking_account.withdraw(quote_cost)
    messages.success(request, _('Succes.'))
except (ObjectDoesNotExist, ValueError):
    messages.error(request, _('no checking account yet or not enough cash.'))
    return HttpResponseRedirect(reverse('deposit_checking_account'))
return render(request, ‘buy.html')

1 个答案:

答案 0 :(得分:0)

情况甚至更糟,因为你还不必要地在数据库中点击exists()电话。不要做任何事情;相反,只需遵循用户的一对一关系:

checking_account = user.checking_account