Saturday, June 20, 2009

ModelAdmin readonly fields

Finalizing my web application, there was a few outstanding patches left to do. One of this I always felt strange why it was left out in the open. Django's admin interface form by default allows you to edit the primary key of the model. I always felt strange why it allowed this as it led to unexpected behavior. My users would edit the primary key expecting the changes to be done on the record which of course did not happen as django created another new object with the new edited id.

In solving this bug I was hoping that django's admin model allowed for something like 'readonly = ( 'id_field')' or something like to that respect. Just thinking out aloud but shouldn't this be automatically done for all primary key fields in ? Shouldn't the primary key be made non editable by default unless explicitly stated in the definition? Even then should the primary key be allowed to be edited? If a user were to be allowed to edit the primary key, would it really be editing or 'cloning' a new object with similar data but differing ids? I haven't really done a thorough search yet but I think by default all the fields is open to edit in the current django's ModelAdmin. Of course you hide the field away by chucking the field in the exclude tuple in your model's admin declaration but what if the user wanted to see that field? I was actually quite surprised when a declaration of fields that should be readonly in my ModelsAdmin did nothing. That was the first way I thought of doing it anyway.

The best would be a new tuple called readonly that would declare fields that are readonly in the change_form. To cut a long story short, I found someone had already created a snippet for it here. Works perfectly and it's exactly what I was looking for. The questions that remain however are:

1. Why isn't this in the core?
2. Should you actually allow primary key fields to be edited ?!


nih said...

its meant to be included in 1.2, so could be a while...

Luke Plant said...

Most people do not use explicit primary keys (using primary_key=True). They use automatic primary keys (a field added by Django). These are not editable in the admin. This is the preferred way to do it, especially when it comes to things like tagging and GenericForeignKey. That's why most people don't come across this bug.

Dougal said...

+1 to what Luke said.

Good to see it will be added in 1.2 though.