About Secure Model Methods

It would be a security flaw if Django templates, especially partly coming from a database, allowed modifying the data in the database, e.g.:

{% for feature_setting in user.feature_settings.all %}
    {{ feature_setting.enable }}
{% endfor %}

To avoid this, set the attribute alters_data = True to the functions or methods that will be exposed in the templates if they change data (custom save(), custom delete(), enable(), disable(), flag(), etc.). Here is an example with the enable() method:

class FeatureSetting(models.Model):
    user = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        related_name="feature_settings",
    )
    feature = models.ForeignKey(
        "Feature",
        on_delete=models.CASCADE,
        related_name="feature_settings",
    )
    is_enabled = models.BooleanField(default=False)

    class Meta:
        unique_together = ("user", "setting")

    def __str__(self):
        status = "enabled" if self.is_enabled else "disabled"
        return f"{self.user}{self.feature} ({status})"

    def enable(self):
        self.is_enabled = True
        self.save()
    enable.alters_data = True

Tips and Tricks Programming Security Django 6.x Django 5.2 Django 4.2