Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can Django models use MySQL functions?

Is there a way to force Django models to pass a field to a MySQL function every time the model data is read or loaded? To clarify what I mean in SQL, I want the Django model to produce something like the following:

On model load: SELECT AES_DECRYPT(fieldname, password) FROM tablename

On model save: INSERT INTO tablename VALUES (AES_ENCRYPT(userinput, password))

like image 399
Tony Avatar asked Dec 07 '22 05:12

Tony


2 Answers

Instead of on model load, you can create a property on your model, and when the property is accessed, it can read the database:

def _get_foobar(self):
    if not hasattr(self, '_foobar'):

        cursor = connection.cursor()
        self._foobar = cursor.execute('SELECT AES_DECRYPT(fieldname, password) FROM tablename')[0]
    return self._foobar
foobar = property(_get_foobar)

Now after loading, you can refer to mything.foobar, and the first access will retrieve the decryption from the database, holding onto it for later accesses.

This also has the advantage that if some of your code has no use for the decryption, it won't happen.

like image 191
Ned Batchelder Avatar answered Dec 10 '22 11:12

Ned Batchelder


I would define a custom modelfield for the column you want encrypted/decrypted. Override the to_python method to run the decryption when the model is loaded, and get_db_prep_value to run the encryption on saving.

Remember to set the field's metaclass to models.SubfieldBase otherwise these methods won't be called.

like image 27
Daniel Roseman Avatar answered Dec 10 '22 12:12

Daniel Roseman