azavea/OTM2 — pull request #268 by ahinz (2013-09-03 14:05:55+00:00)
Title: Add user defined collection backend

User defined collections are similar to scalar collections in that they
both are defined as UserDefinedFieldDefinitions. However, as the name
suggests, a single UDFD can represent a set of named tuples.

For example:

```
UserDefinedFieldDefinition.objects.create(
instance=self.instance,
model_type='Plot',
datatype=json.dumps([
{'type': 'string',
'name': 'action'},
{'type': 'int',
'name': 'height'}]),
iscollection=True,
name='Stewardship'
```

Then we can play around with it using the `udf` pseudo field:

```
p = Plot.objects.get(pk=some_pk)
p.udf['Stewardship'].append({'action': 'rake', 'height': 12})
p.udf['Stewardship'].append({'action': 'climb', 'height': 12})
p.save_with_user(some_user_with_permissions)

p2 = Plot.objects.get(pk=some_pk)

assert p2.udf['Stewardship'][0]['action'] == 'rake'
assert p2.udf['Stewardship'][1]['action'] == 'climb'
```

There are specialized authorizable semantics for collection
fields. Using the above as an example, the udf can be edited if the user
has some sort of editing permission for model 'Plot' and field
'udf:Stewardship'.

The biggest current issue is the awkward couping between the audit
system, the authorizable system and the UDF system (as witnessed by the
function-level imports in audit.py from udf.py). That being said, this
is the last planned change to those systems so we can refactor freely
from here on out.