防止在模板中调用敏感方法

当一个对象暴露给模板上下文时,它的无参数方法是可用的。当这些函数是 getters 时,这很有用。但如果这些方法改变某些数据或产生一些副作用,则可能会产生危险。尽管你可能信任模板编写者,但他可能不会意识到函数的副作用,或者认为错误地调用了错误的属性。

鉴于以下模型:

class Foobar(models.Model):
    points_credit = models.IntegerField()

    def credit_points(self, nb_points=1):
        """Credit points and return the new points credit value."""
        self.points_credit = F('points_credit') + nb_points
        self.save(update_fields=['points_credit'])
        return self.points_credit

如果你错误地在模板中写这个:

 You have {{ foobar.credit_points }} points!

这将在每次调用模板时增加点数。你甚至可能都没注意到它。

要防止这种情况,你必须将 alters_data 属性设置为 True 到具有副作用的方法。这将无法从模板中调用它们。

def credit_points(self, nb_points=1):
    """Credit points and return the new points credit value."""
    self.points_credit = F('points_credit') + nb_points
    self.save(update_fields=['points_credit'])
    return self.points_credit
credit_points.alters_data = True