Django Prevent sensitive methods from being called in templates


Example

When an object is exposed to the template context, its arguments-less methods are available. This is useful when these functions are "getters". But it can be hazardeous if these methods alter some data or have some side effects. Eventhough you likely trust the template writer, he may not be aware of a function's side effects or think call the wrong attribute by mistake.

Given the following model:

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

If you write this, by mistake, in a template:

 You have {{ foobar.credit_points }} points!

This will increment the number of points each time the template is called. And you may not even notice it.

To prevent this, you must set the alters_data attribute to True to methods that have side effects. This will make it impossible to call them from a template.

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