picostitch
crafting (and) JavaScript

Django read-only Model

How can I make a django model read-only? There seems to be no metadata option read_only or alike in django. Well it's easy to do in the admin, but I am creating a model that serves a DB view, which is, at least in MariaDB not writable. So I want to throw an error when someone tries to update data in the view.

In the end it is very simple:

from django.db import models

class ReadOnlyModel:
    def save(self, **kwargs):
        raise Exception('This is a DB view, there is no saving possible.')

class Person(ReadOnlyModel, models.Model):
    name = models.CharField(max_length=255)

The class ReadOnlyModel simply overrides the save method and by mixing it in as the first inherited class its save() method is found first.

Why first? Python's multiple inheritance is "depth-first, left-to-right", which means if save() is found on the first class it's used and the exception is thrown.

Below see what happens when any function is called, that tries to save data.

>>> Person(id=1).save()
>>> Person.objects.create(id=1)
>>> Person.objects.update_or_create(id=1)
>>> Person.objects.get_or_create(id=1)

File "dbviews.py", line 4, in save
  raise Exception('This is a DB view, there is no saving possible.')
Exception: This is a DB view, there is no saving possible.

Disadvantages mentioned by Manuel Strehl:

disadvantage: bulk methods like .update() on sets would still try to update the DB.