def watch_changes(model, ignore=[], master_key=None, **options):
    """Declare the specified model to be "observed" ("watched") for changes.
    Each change to an object comprising at least one watched field
    will lead to an entry to the `Changes` table.

    `ignore` should be a string with a space-separated list of field
    names to be ignored.
    
    All calls to watch_changes will be grouped by model.

    """
    if isinstance(ignore, basestring):
        ignore = fields.fields_list(model, ignore)
    if isinstance(master_key, basestring):
        fld = model.get_data_elem(master_key)
        if fld is None:
            raise Exception("No field %r in %s" % (master_key, model))
        master_key = fld
    if isinstance(master_key, fields.RemoteField):
        get_master = master_key.func
    elif master_key is None:
        get_master = return_self
    else:
        def get_master(obj):
            return getattr(obj, master_key.name)
    ignore = set(ignore)
    cs = model.change_watcher_spec
    if cs is not None:
        ignore |= cs.ignored_fields
    for f in model._meta.fields:
        if not f.editable:
            ignore.add(f.name)
    model.change_watcher_spec = WatcherSpec(ignore, get_master)
dataset/ETHPy150Open lsaffre/lino/lino/modlib/changes/models.py/watch_changes/original