Hello guys, I'm running django on a legacy database and in some cases the values stored in the tables have to be converted before the can be displayed and also have to be converted bevore bein saved to the database.
Example: A table for storing IP addresses: The address field contains values that are packed binary format representations of the human readable value e.g: 000000000000000000000000d55f026c resolves to 213.95.2.108. I already figured out how to convert between those tow back and forth with the socket module. I also figured out how I can make it work in django. But I'm not happy with the solution I found and I suspect that there might be a better way to do it. Currently I'm doing it in the following way: I have a custom ModelField: class IpAddrField(models.CharField): __metaclass__ = models.SubfieldBase default_error_messages = { 'invalid' : _('%s ist keine valide IP-Adresse.') } def get_internal_type(self): return "CharField" def to_python(self, value): print " ---------- ModelField to_python got: %s" % value value = db_to_ipaddr(value) print " ---------- ModellField to_python returning: %s" % value return value def clean(self,value,model_instance): print " ---------- ModelField clean got: %s" % value try: value = ipaddr_to_db(value) except (socket.error, ValueError): raise exceptions.ValidationError(self.error_messages['invalid'] % value) self.validate(value, model_instance) self.run_validators(value) print " ---------- ModelField clean returning: %s" % value return value def get_prep_value(self,value): print " ---------- MoldelField get_prep got: %s" % value value = ipaddr_to_db(value) print " ---------- MoldelField get_prep returning: %s" % value return value def formfield(self, **kwargs): defaults = {'form_class': IpAddrFormField} defaults.update(kwargs) return super(IpAddrField, self).formfield(**defaults) The code for the custom formField looks like this: class IpAddrFormField(forms.CharField): default_error_messages = { 'invalid' : _('%s ist keine valide IP-Adresse.') } def to_python(self,value): print " ---------- FormField to_python got: %s" % value try: value = ipaddr_to_db(value) except socket.error: raise exceptions.ValidationError(self.error_messages['invalid'] % value) print " ---------- FormField to_python returning: %s" % value return value def clean(self,value): "convert the literal value to the db representation" print " ---------- FormField clean got: %s" % value try: value = self.to_python(value) except socket.error: raise exceptions.ValidationError(self.error_messages['invalid'] % value) self.validate(value) self.run_validators(value) print " ---------- FormField clean return: %s" % value return value So when I run this code and send a form with a valid IP address it works. Here is the log output of a successful update: ---------- ModelField to_python got: 000000000000000000000000d55f026d ---------- ModellField to_python returning: 213.95.2.109 ---------- FormField clean got: 213.95.2.108 ---------- FormField to_python got: 213.95.2.108 ---------- FormField to_python returning: 000000000000000000000000d55f026c ---------- FormField clean return: 000000000000000000000000d55f026c ---------- ModelField to_python got: 000000000000000000000000d55f026c ---------- ModellField to_python returning: 213.95.2.108 ---------- ModelField clean got: 213.95.2.108 ---------- ModelField clean returning: 000000000000000000000000d55f026c ---------- ModelField to_python got: 000000000000000000000000d55f026c ---------- ModellField to_python returning: 213.95.2.108 ---------- ModelField to_python got: 000000000000000000000000d55f026d ---------- ModellField to_python returning: 213.95.2.109 ---------- MoldelField get_prep got: 213.95.2.108 ---------- MoldelField get_prep returning: 000000000000000000000000d55f026c ---------------- in post save (this is a post_save hook, not sure if this is relevant here) ---------- MoldelField get_prep got: 213.95.2.108 ---------- MoldelField get_prep returning: 000000000000000000000000d55f026c ---------------- in post save (this is a post_save hook, not sure if this is relevant here) ---------------- in post save (this is a post_save hook, not sure if this is relevant here) [18/Feb/2011 10:13:56] "POST /services/ipkunde/15679/update/ HTTP/1.1" 302 0 ---------- ModelField to_python got: 000000000000000000000000d55f026c ---------- ModellField to_python returning: 213.95.2.108 This is a lot of back and forth conversion and I'm not so happy with this. The code might break if the django validation thing changes slightly or something unexpected happens. On top of that, I feel like working against the ideas of whole validation thing. Can someone suggest a better solution? Maybe an easier one. Or a more stable one? There are quite some fields where I have to do such conversions. I'm really trying to find a clean solution which is not just tricking the framework. Looking forward to you comments... Regards Roman -- You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to django-users@googlegroups.com. To unsubscribe from this group, send email to django-users+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/django-users?hl=en.