Several 'virtual' fields controlled by an unique custom field ?

1 view
Skip to first unread message

Alexandre Vaissiere

unread,
Feb 9, 2009, 5:47:17 PM2/9/09
to django...@googlegroups.com
Hello,

I have a model that looks like this :

class Entry(models.Model):
data = models.TextField()
data_html = models.TextField(editable=False)

def save(self):
self.data_html = convert(self.data)
super(Entry, self).save()

It works fine, but an exception raised by convert function would lead to
a 500 response. So I pondered myself, and came back with a custom field
and its associated form field:

class CustomTextField(TextField):
def __init__(self, *args, **kwargs):
super(CustomTextField, self).__init__(*args, **kwargs)

def formfield(self, **kwargs):
defaults = {'form_class': CustomTextFormField}
defaults.update(kwargs)
return super(CustomTextField, self).formfield(**defaults)

class CustomTextFormField(forms.CharField):
def clean(self, value):
value = super(CustomTextFormField, self).clean(value)
try:
convert(value)
except Exception, e:
raise forms.ValidationError(e.message)
return value

Now, it works really fine, I have a pretty error message when i make
some mistake during edition. Still I see two problems:

* The convert() process is done twice,
* If i want to reuse my CustomTextField elsewhere, i will need to
override the Model.save() method in every model.

My idea is that CustomTextField should manage under the hood two model
fields: data and data_html, taking off the burden of declaring and
managing this from the model.

Unfortunately I have no idea how to achieve this.

Ideally, my model would look like this:

class Entry(models.Model):
data = CustomTextField()

>>> convert(u'flying')
u'<b>flying</b>'
>>> e = Entry()
>>> e.data = u'flying'
>>> e.data_html
u'<b>flying</b>'

select * from app.entry;
|| id || data || data_html ||
|| 1 || flying || <b>flying</b> ||

Does someone have some link or idea how doing that ? I failed to find it
in the documentation (or more probably failed to properly understand it).

Thank you in advance,

Kind regards,
Alexandre.

Reply all
Reply to author
Forward
0 new messages