[django] model field für python dicts...
Verfasst: Samstag 18. April 2009, 23:53
Hier hab ich mir ein DictField gebaut. Damit kann man ein python dict in ein django model field packen, soweit klappt alles. Ich finde es nur ein wenig umständlich:
Damit man auch im django admin panel einen DB Eintrag "normal" editieren kann, habe ich ein eigenes form field und widget gemacht. Und da liegt auch meine Frage: Ich finde es dumm, das man an zwei Stellen die Wandlung python<->json machen muß. Im model field, im form field und im form widget...
Ich Frage mich wie ich im form field und im widget Zugriff auf die model instance haben kann?
EDIT: btw. Natürlich könnte man auch andere datentypen die json kann nehmen. Ich brauche aber nur dict...
EDIT2: Hier noch ein ähnliches Beispiel: http://trac.pylucid.net/browser/branche ... y?rev=1906
Code: Alles auswählen
def serialize(data):
return simplejson.dumps(data, sort_keys=True, indent=4)
def deserialize(stream):
return simplejson.loads(stream)
class DictFormWidget(forms.Textarea):
""" form widget for preferences dict """
def render(self, name, value, attrs=None):
"""
FIXME: Can we get the original non-serialized db value here?
"""
value = serialize(value)
return super(DictFormWidget, self).render(name, value, attrs)
class DictFormField(forms.CharField):
""" form field for preferences dict """
widget = DictFormWidget
def clean(self, value):
"""
validate the form data
FIXME: How can we get the pref form class for validating???
"""
value = super(DictFormField, self).clean(value)
try:
return deserialize(value)
except Exception, err:
raise forms.ValidationError("Can't deserialize: %s" % err)
class DictField(models.TextField):
"""
A dict field.
Stores a python dict into a text field.
"""
__metaclass__ = models.SubfieldBase
def to_python(self, value):
""" decode the data dict using simplejson.loads() """
if isinstance(value, dict):
return value
return deserialize(value)
def get_db_prep_save(self, value):
"Returns field's value prepared for saving into a database."
assert isinstance(value, dict)
return serialize(value)
def formfield(self, **kwargs):
# Always use own form field and widget:
kwargs['form_class'] = DictFormField
kwargs['widget'] = DictFormWidget
return super(DictField, self).formfield(**kwargs)
Ich Frage mich wie ich im form field und im widget Zugriff auf die model instance haben kann?
EDIT: btw. Natürlich könnte man auch andere datentypen die json kann nehmen. Ich brauche aber nur dict...
EDIT2: Hier noch ein ähnliches Beispiel: http://trac.pylucid.net/browser/branche ... y?rev=1906