how to make readonly in change but editable in add?

171 views
Skip to first unread message

snipinben

unread,
Aug 3, 2010, 2:36:56 PM8/3/10
to django...@googlegroups.com

I was wondering how to make a field readonly when you click on it or want to
change the record. and i have done that with the readonly_feilds method. but
that makes it to where you cant add information to that feild when you add a
new record. is there something i can use where you are not able to edit a
feild in the change view, but when you add new, you are able to edit the
field until you press save? thanks alot
--
View this message in context: http://old.nabble.com/how-to-make-readonly-in-change-but-editable-in-add--tp29338689p29338689.html
Sent from the django-users mailing list archive at Nabble.com.

shmengie

unread,
Aug 3, 2010, 11:03:18 PM8/3/10
to Django users
I cobbled these two classes together which work very nicely for me,
wish they could make into django.
Drop these two classes into a util.py and import them instead of Form
or ModelForm. When you want your form readonly instantiate it with
"form=MyForm(record, readonly=True)"

class roForm(forms.Form):
def __init__(self, *args, **kwargs):
self.readonly = False
if kwargs.has_key('readonly'):
if kwargs['readonly']:
self.readonly = True
kwargs.pop('readonly')
super(roForm, self).__init__(*args, **kwargs)
if self.readonly:
for key in self.fields.iterkeys():
self.fields[key].widget.attrs['disabled'] = True


class roModelForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
self.readonly = False
if kwargs.has_key('readonly'):
if kwargs['readonly']:
self.readonly = True
kwargs.pop('readonly')
super(roModelForm, self).__init__(*args, **kwargs)
if self.readonly:
for key in self.fields.iterkeys():
self.fields[key].widget.attrs['disabled'] = True


On Aug 3, 2:36 pm, snipinben <benjamin.calderon1...@gmail.com> wrote:
> I was wondering how to make a field readonly when you click on it or want to
> change the record. and i have done that with the readonly_feilds method. but
> that makes it to where you cant add information to that feild when you add a
> new record. is there something i can use where you are not able to edit a
> feild in the change view, but when you add new, you are able to edit the
> field until you press save? thanks alot
> --
> View this message in context:http://old.nabble.com/how-to-make-readonly-in-change-but-editable-in-...

Paulo Almeida

unread,
Aug 4, 2010, 4:13:09 AM8/4/10
to django...@googlegroups.com
Actually, what he wanted was just to override a field, and not the whole form, but he can do it with slight modifications of your code. He would override the form class he wants to modify, instead of creating a generic one, and instead of iterating all the fields he would just set the relevant one(s) read only.

- Paulo 

--
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.


Steve Holden

unread,
Aug 4, 2010, 7:57:24 AM8/4/10
to django...@googlegroups.com
On 8/3/2010 11:03 PM, shmengie wrote:
> I cobbled these two classes together which work very nicely for me,
> wish they could make into django.
> Drop these two classes into a util.py and import them instead of Form
> or ModelForm. When you want your form readonly instantiate it with
> "form=MyForm(record, readonly=True)"
>
> class roForm(forms.Form):
> def __init__(self, *args, **kwargs):
> self.readonly = False
> if kwargs.has_key('readonly'):
> if kwargs['readonly']:
> self.readonly = True
> kwargs.pop('readonly')
> super(roForm, self).__init__(*args, **kwargs)
> if self.readonly:
> for key in self.fields.iterkeys():
> self.fields[key].widget.attrs['disabled'] = True
>
Just a stylistic point. It's easy to second-guess someone else's code
when you have the liberty of scrutinizing it at what I sometimes
laughingly call "leisure", so I don't want this to be interpreted as
being critical, but the code might (?) be easier to read (barring typos) as:

class roForm(forms.Form):
def __init__(self, *args, **kwargs):

self.readonly = 'readonly' in kwargs
if self.readonly:


kwargs.pop('readonly')
super(roForm, self).__init__(*args, **kwargs)
if self.readonly:
for key in self.fields.iterkeys():
self.fields[key].widget.attrs['disabled'] = True

regards
Steve

shmengie

unread,
Aug 4, 2010, 6:52:46 PM8/4/10
to Django users
Shamefully, I didn't even give it a good once over before posting it.
However, I have read through it, and I'm not too ashamed ;) More
comments would be nice, but I was more concerned with the results at
the time and it's not terribly complex code, so I think it stands well
on it's own.

I couldn't use this refactoring, because I use readonly=False
depending on circumstance before instantiating the form, this would
create a readonly form which wouldn't be desired.

if kwargs['readonly']: # tests the arg 'readonly' to see if it
evaluates to a True expression. But before testing it's evaluation,
you need to ensure the arg is in the list, hence '''if
kwargs.has_key('readonly'):'''

My original code may not be perfect but it works ;)


Shawn Milochik

unread,
Aug 5, 2010, 11:24:22 AM8/5/10
to django...@googlegroups.com
You can do this very easily by tweaking your model as follows:

1. Override __init__() and store the value of that field in a
temporary value, such as self.old_status.

2. Override save() and before you call the super() save, check if
self.pk (meaning the instance is not new). If so, and self.old_status
!= self.current_status, you can raise an exception.

For extra credit you might want to tweak your ModelForm so that it
will raise a ValidationError, because otherwise it'll validate and
then you'll get a 500 error when the save() on the model is attempted.
However, I like having the exception raised at the model level because
it will protect your data in case the model is accessed by some means
other than your ModelForm.

Shawn

shmengie

unread,
Aug 5, 2010, 12:31:56 PM8/5/10
to Django users
I think it's better to let the user know the fields exist and may not
be changed, than to present them with editable fields that may not.

Has to do with consistent presentation and notification. Data
validation needs to be implemented in either event, because you cannot
guarantee the user will show the same respect.

Shawn Milochik

unread,
Aug 5, 2010, 1:11:34 PM8/5/10
to django...@googlegroups.com
On Thu, Aug 5, 2010 at 12:31 PM, shmengie <1st...@gmail.com> wrote:
> I think it's better to let the user know the fields exist and may not
> be changed, than to present them with editable fields that may not.
>

I agree. That's not incompatible with my solution. I would expect the
user to be informed of the policy rather than just have changes
ignored.

I chose to present the simplest possible explanation you could use to
do what you wanted instead of going into great depth writing your
ModelForms for you because it was easier to do. I take for granted
that there is more than I know (or will ever know) going on in your
project and I expect that you will ignore or adapt my suggestions as
you see fit.

Shawn

Reply all
Reply to author
Forward
0 new messages