- Author:
- StanislavKraev
- Posted:
- June 30, 2011
- Language:
- Python
- Version:
- 1.2
- Score:
- 1 (after 1 ratings)
These decorators can be used to make some model/form fields readonly.
Sample usage:
# Use this decorator on form with readonly fields.`
@modelform_with_readonly_fields`
class FooAdminForm(forms.ModelForm):`
...
# This decorator shoud be used to protect selected fields `
# from modification after initial save.`
@has_readonly_fields`
class Foo(models.Model):`
read_only_fields = ('name', )`
...
Result will be the same as shown in this post: Readonly field and Readonly model field
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | from django.db import models
# Decorator for django models that contain readonly fields.
def has_readonly_fields(original_class):
def store_read_only_fields(sender, instance, **kwargs):
if not instance.id:
return
for field_name in sender.read_only_fields:
val = getattr(instance, field_name)
setattr(instance, field_name + "_oldval", val)
def check_read_only_fields(sender, instance, **kwargs):
if not instance.id:
return
for field_name in sender.read_only_fields:
old_value = getattr(instance, field_name + "_oldval")
new_value = getattr(instance, field_name)
if old_value != new_value:
raise ValueError("Field %s is read only." % field_name)
models.signals.post_init.connect(store_read_only_fields, original_class, weak=False) # for load
models.signals.post_save.connect(store_read_only_fields, original_class, weak=False) # for save
models.signals.pre_save.connect(check_read_only_fields, original_class, weak=False)
return original_class
# decorator for django modelforms that contain readonly fields
def modelform_with_readonly_fields(origin_class):
origin_init = origin_class.__init__
def lambder(field, old_method):
return lambda this : clean_field(this, field, old_method)
def clean_field(self, field_name, old_method):
instance = getattr(self, 'instance', None)
if instance and instance.id:
return getattr(instance, field_name)
else:
if old_method:
return old_method(self)
else:
return self.cleaned_data.get(field_name, None)
def __init__(self, *args, **kws):
origin_init(self, *args, **kws)
instance = getattr(self, 'instance', None)
if instance and instance.id:
for field in origin_class.Meta.model.read_only_fields:
self.fields[field].required = False
self.fields[field].widget.attrs['disabled'] = 'disabled'
origin_class.__init__ = __init__
for field in origin_class.Meta.model.read_only_fields:
field_name = "clean_" + field
old_method = getattr(origin_class, field_name, None)
setattr(origin_class, field_name, lambder(field, old_method))
return origin_class
|
More like this
- Template tag - list punctuation for a list of items by shapiromatron 9 months, 3 weeks ago
- JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 10 months ago
- Serializer factory with Django Rest Framework by julio 1 year, 4 months ago
- Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 5 months ago
- Help text hyperlinks by sa2812 1 year, 6 months ago
Comments
Please login first before commenting.