Reputation: 11
Is it possible to pass in values to the init of a custom model field?
Example code:
class Example(models.Model):
user = models.ForeignKey(User)
text = EncryptedCharField('Text',max_length=255)
class BaseEncryptedField(models.Field):
def __init__(self, *args, **kwargs):
self.cipher = AES.new(key)
models.Field.__init__(self, *args, **kwargs)
def to_python(self, value):
if isinstance(value, EncryptedString):
return self.cipher.decrypt(binascii.a2b_base64(str(value))).split(EOD)[0]
return value
def get_db_prep_value(self, value):
if value is not None and not isinstance(value, EncryptedString):
saltlength = self.cipher.block_size - (len(value) + len(EOD)) % self.cipher.block_size
if saltlength:
value = ''.join([value,EOD,generate_salt(saltlength)])
value = EncryptedString(binascii.b2a_base64(self.cipher.encrypt(value)))
return value
In the init function, I'd like to pass a key (which is stored in the user profile and changes depending on the user) in to set up the AES cipher, but I can't seem to figure out how to get it in.
Upvotes: 1
Views: 405
Reputation: 320
Try this. In class Example:
text = EncryptedCharField('Text', max_length=255, key=pass_the_user's_key_here)
Then in BaseEncryptedField.init:
self.cipher = AES.new(kwargs['key'])
Upvotes: 0
Reputation: 15965
Not sure I understand your problem... but here goes.
If you pass the argument to the constructor of your model (init), it'll be available in the "args" collection. You can also pass arguments as a map (so you can access them by name through kwargs).
So you should do something like args[0], to get your key. (Can't remember exactly if the first passed parameter is at index 0 or 1, you can always try it out/debug =))
Upvotes: 1