Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I make a Django model read-only?

Tags:

Is it possible to make a Django model read only? No creating, updating etc.

N.B. this question is different to:

Make a Django model read-only? (this question allows creation of new records)

Whole model as read-only (only concerns the Django admin interface - I'd like the model to be read only throughout the whole app)

like image 569
Ollie Glass Avatar asked Aug 28 '12 11:08

Ollie Glass


People also ask

What is read only Django?

Instead, django-read-only uses always installed database instrumentation to inspect executed queries and only allow those which look like reads. It uses a “fail closed” philosophy, so anything unknown will fail, which should be fairly reasonable.

How do I override model save in Django?

Whenever one tries to create an instance of a model either from admin interface or django shell, save() function is run. We can override save function before storing the data in the database to apply some constraint or fill some ready only fields like SlugField.

What is Django's ORM?

One of the most powerful features of Django is its Object-Relational Mapper (ORM), which enables you to interact with your database, like you would with SQL. In fact, Django's ORM is just a pythonical way to create SQL to query and manipulate your database and get results in a pythonic fashion.

What is timestamped model in Django?

TimeStampedModel - An Abstract Base Class model that provides self-managed created and modified fields.


2 Answers

Override the save and delete methods for the model. How are you planning to add objects to your model?

def save(self, *args, **kwargs):      return  def delete(self, *args, **kwargs):      return 
like image 104
Mikael Avatar answered Oct 20 '22 13:10

Mikael


Database Routers

To take more precautions that your model is read-only, you can use the DATABASE_ROUTERS setting to disable writing on a per model basis:

# settings.py DATABASE_ROUTERS = ('dbrouters.MyCustomRouter', )   # dbrouters.py class MyCustomRouter(object):     def db_for_write(self, model, **hints):         if model == MyReadOnlyModel:             raise Exception("This model is read only. Shame!")          return None 

I would consider this an insurance policy, and not the primary way to solve the problem. Mikael's answer, for example, is great but doesn't cover all cases because some Django operations bypass delete and save methods.

See Juan José Brown's answer in Django - how to specify a database for a model? for a more detailed description of using a database router.

Setting permissions on database user

However, even the database router approach seems to have loopholes, i.e. there are ways to send SQL from Django that bypasses your router code. To be absolutely sure of making something readonly, you should set the permissions on the database user. This question describes how to set up a readonly postgreql user, which could then be the database user set by Django in settings.DATABASES.

like image 45
Mark Chackerian Avatar answered Oct 20 '22 14:10

Mark Chackerian