> That's not a great answer, but in the meantime, you might want to take
> a look at the lazy instantiation in the GIS branch[1]. That code isn't
> exactly what you want, but it might help get you started on a
> descriptor-based approach to do what you're asking for until there's a
> proper solution.

Thanks Marty - that was exactly what I was looking for.  Using a proxy
with descriptors solved my problem - what a nifty, sneaky little
trick!

I had some difficulty determining the context of the __set__ calls -
on loading from the db, the inbound value is the encrypted db value
(which needs to be encrypted only then), or due to a user changing the
value (in clear text - in which case the setter should not decrypt the
value) - and therefore the flag.

Here's my take on it:

class CharEncryptProxy(object):
    def __init__(self, field):
        self._field = field
        self._decrypted = False

    def __get__(self, obj, type=None):
        return obj.__dict__[self._field.attname]

    def __set__(self, obj, value):
        # only decrypt first time if set by db
        if (not self._decrypted) and (value != ''):
            obj.__dict__[self._field.attname] =
self._field._decrypt(value)
        else:
            obj.__dict__[self._field.attname] = value
        self._decrypted = True

class CharEncryptField(models.CharField):
    def _encrypt(self, value):
        if value is not None:
            value = ''.join([chr(ord(char)+1) for char in str(value)])
        return value

    def _decrypt(self, value):
        if value is not None:
            value = ''.join([chr(ord(char)-1) for char in str(value)])
        return value

    def get_internal_type(self):
        return "CharField"

    def get_db_prep_save(self, value):
        value = self._encrypt(value)
        return super(CharEncryptField,
self).get_db_prep_save(value)

    def contribute_to_class(self, cls, name):
        super(CharEncryptField, self).contribute_to_class(cls, name)
        # override with proxy
        setattr(cls, self.attname, CharEncryptProxy(self))



Works like a charm - thanks again for putting me on the right track!


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to