DB-Views or read-only tables in models

1,022 views
Skip to first unread message

bvdb

unread,
Jan 25, 2011, 11:19:37 AM1/25/11
to Django users
A developer sometimes has to access and present data that existed
before his application. Common practice is for a database
administrator to define a database view (with a CREATE VIEW sql
command, not to be confused with the V in MVC) and give the Django
developer access to this. This is only a read access because in most
cases it is not possible or desireable to allow an UPDATE on a view.

Now I am new to Django, have some experience with databases - and
couldn't find a "read-only attribute" when defining a model.
Without knowing that a view - that is accessed with the same SELECT
syntax as a table - is read-only Django would for example generate an
admin interface that produces errors, and leave the user wondering
why.
It makes also sense in some cases to define a table read-only for a
model even it is fully accessible by the Django team.

Is it really not possible to define read-only access in Djangos ORM?
Or maybe I just overlooked the description?

Russell Keith-Magee

unread,
Jan 25, 2011, 9:22:50 PM1/25/11
to django...@googlegroups.com

Essentially the answer is no.

Django doesn't have a built-in representation of a view. You can't
define a view in the same way that you would define a model, for
example. This has long been on my 'things I want to look at' list, but
I've never got around to it.

You can define a Django model as a wrapper around a view by marking it
managed, but that doesn't make the model read-only -- it just prevents
Django from trying to create the model during syncdb.

From the perspective of the admin, you can define a field to be
readonly, but that's purely a data display level concern, and is
controlled on a per-field basis. With a bit of effort your could make
an admin view that is effectively readonly, but there isn't a simple
single switch to do this.

Another approach is to use the databrowse app; that's purely a
readonly display. It's not as mature or pretty as the admin, but it
exists, and you might be able to use it.

Yours,
Russ Magee %-)

George Silva

unread,
Jan 25, 2011, 10:32:14 PM1/25/11
to django...@googlegroups.com
Perhaps you could override the save method and make it like this:
 
def save(self,*args,**kwargs):
   pass
 
Would that work? This is also a curiosity I have, but didn't have a chance to test it.
 
Any thoughts?
 
George


--
You received this message because you are subscribed to the Google Groups "Django users" group.
To post to this group, send email to django...@googlegroups.com.
To unsubscribe from this group, send email to django-users...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/django-users?hl=en.




--
George R. C. Silva

Desenvolvimento em GIS
http://blog.geoprocessamento.net

Chris Matthews

unread,
Jan 26, 2011, 12:28:43 AM1/26/11
to django...@googlegroups.com
Not sure if http://docs.djangoproject.com/en/dev/ref/contrib/admin/actions/ will be of some help. See admin.site.disable_action('delete_selected')
; but this is only via the admin app. You could build some logic in the model by overriding the save() method, conditionally, based upon user. So your developers/administrators can have full access but 'normal' users not.

--

Simone Dalla

unread,
Jan 26, 2011, 2:16:37 AM1/26/11
to django...@googlegroups.com


2011/1/25 bvdb <bv...@kanka.de>
Define a model for your db view and set the meta option 

managed=False


--
Simo

- Registered Linux User #395060

- Software is like sex, it is better when it is free  --> Linus B. Torvalds

bvdb

unread,
Jan 26, 2011, 9:14:32 AM1/26/11
to Django users
On Jan 26, 3:22 am, Russell Keith-Magee <russ...@keith-magee.com>
wrote:
> Django doesn't have a built-in representation of a view. ..
>
> You can define a Django model as a wrapper around a view by marking it
> managed, but that doesn't make the model read-only -- it just prevents
> Django from trying to create the model during syncdb.

Ok, thanks for this clear answer.
I've noted the "managed" option that might avoid errors on a sync but
as django still thinks these tables are updateable it's not a real
solution - and it's not wise to recommend django for the situations
mentioned in my first post.

So the django ORM is in the same situation as the Ruby-on-Rails ORM.
But, as opposed to Ruby, a possible solution already exists in the
form of SQLalchemy.
This approach has already been followed:
http://code.google.com/p/django-sqlalchemy/

Progress in this project seems a bit low, but maybe one day some
enlighted ghosts will take up the torch ...

Aryeh Leib Taurog

unread,
Jan 27, 2011, 9:21:57 AM1/27/11
to Django users
I am curious to know exactly what behavior you are looking for.
Presumably you would want the standard ORM behavior as far as Read
operations are concerned. It would seem to me that for Create,
Update, and Delete operations, the possibilities are:

1. run-time error from the interpreter (method doesn't even exist)
2. run-time error from the framework (method disallowed)
3. run-time error from the db (view is read-only)
4. no-op (method exists, silently does nothing)

The solution Russell Keith-Magee suggested would give you #2, but I
imagine you wouldn't want that because it involved hitting the db
unnecessarily. On the other hand, how often do you expect this to
actually occur in production?

With George Silva's suggestion, you could get #4 or #2, though you'd
might have to override more than save(), you might want to change
save.alters_data to False. You'd probably also want to subclass the
QuerySet and override all the data modifying methods. Then subclass
the model Manager and override its get_query_set to return an instance
of your ReadOnlyQuerySet.

If, as your original post indicated, your main concern is the admin
interface, then obviously none of the above are acceptable, because
your UI will contain elements that either cause server errors or don't
do anything. I haven't looked at the the django-sqlalchemy project,
so I don't know if that project addresses this issue, but obviously
just using an ORM which provides read-only models won't change the
fact that there's no read-only admin.

I haven't tried this, but if you are using Django 1.2, you could
probably make a read-only admin interface fairly easily:
1. See Chris Matthews' suggestion for removing the delete action
2. Supply your own admin template which won't include 'add' or 'save'
buttons if the model is marked read-only
3 Subclass ModelAdmin and set readonly_fields to automatically
include all fields on the model.

Regards,
Aryeh Leib Taurog

bvdb

unread,
Jan 28, 2011, 6:37:41 PM1/28/11
to Django users
Thanks for describing the four possible reactions.
My main concern is organisation, alas I imagine a Django solution, not
just one for me.
So the model needs to know about the view, i.e. we'd need a read-only
attribute in models.py table definitions, so that
a) Developer sets the attribute manually in models.py
or
b) manage.py inspect recognizes the views and sets the attribute

Then I can use the attribute in my code, and I'd expect admin to leave
away the Update/create option in this case.
Reply all
Reply to author
Forward
0 new messages