initcrash/django-denorm — pull request #28 by gerdemb (2013-07-31 10:46:39+00:00)
Title: @depend_on

Here's my first attempt at adding a @depend_on() iterator as documented in Issue #25. All tests pass on sqlite. I have not made changes for postgres or mysql yet, but they should be straightforward.

The only user-facing changes are:

Removal of all `skip` parameters.
Replacement of `@depend_on_related` with `@depend_on`.

Reviewing tests.py should give you a flavor of the changes.

Major internal API changes include:

Two-stage registration and setup of denorms. All denorms are registered by the class_prepared signal and then setup after all the models are loaded. This is necessary, because backwards relationships are not available until the other models has been loaded and since we are now depending on field names instead of model names, we have no way of knowing what backward fields point to until all the models have been loaded.

Triggers have a new `condition` parameter that when set, limits the triggers to when the condition is true. A new TriggerConditionFieldChange class is used to create conditions to update when only certain fields are changed.

TriggerSet no longer attempts to merge similar triggers. Instead a numbered SQL trigger is created for each Trigger class. This was necessary, as sqlite allows only one condition per trigger.

CallbackDenorm is removed and the trigger functionality added to CallbackDependOnField.

helpers.py was removed as the code is no longer needed

Concerns:

I have placed code at the end of models.py to setup all the denorms. I am not sure if this guarantees that all the models are loaded, but it is working in the test app.

I originally proposed that `@depend_on(‘foreignkey’)` would update the field when the other model was inserted or deleted, but not updated and that `@depend_on(‘foreignkey__other_field’)` would also update the field only when other_field changed, but now I think that it might make more sense for `@depend_on(‘foreignkey’)` to update on inserts, deletes or updates to the other model. To catch only inserts and deletes, the AggregateField could be used. It also seems that the CacheKeyFields depends on catching all updates in another model.

I am not sure if the GenericRelation fields are really working correctly. I was able to remove some code related to them in Trigger.sql() without breaking any tests, but I’m not sure if that was correct

There is a note about a problem with PostGIS fields in postgres. Is this code still necessary? My TriggerConditionFieldChange class only stores field names and it would be nice not to have to keep the database types around too.

Would appreciate any comments or feedback you have about these changes.

Cheers,
Ben