Exemple #1
0
def _memoize_reset(reference, instance, **kwargs):
    "Resets the specified instance relative to ``reference``"
    # popped so it does not get included in the config for the signal
    memo = kwargs.pop('memo', None)

    # for every call, keep track of the reference and the object (fork).
    # this is used for recursive calls to related objects. this ensures
    # relationships that follow back up the tree are caught and are merely
    # referenced rather than traversed again.
    if memo is None:
        memo = utils.Memo()
    elif memo.has(reference):
        return memo.get(reference)

    if not isinstance(instance, reference.__class__):
        raise TypeError('The instance supplied must be of the same type as the reference')

    instance._commits = utils.Commits(reference)
    memo.add(reference, instance)

    # default configuration
    config = {
        'fields': None,
        'exclude': ['pk'],
        'deep': False,
        'commit': True,
    }

    # update with user-defined
    config.update(kwargs)

    # pre-signal
    signals.pre_reset.send(sender=reference.__class__, reference=reference,
        instance=instance, config=config, **kwargs)

    fields = config['fields']
    exclude = config['exclude']
    deep = config['deep']
    commit = config['commit']

    # no fields are defined, so get the default ones for shallow or deep
    if not fields:
        fields = utils._default_model_fields(reference, exclude=exclude, deep=deep)

    kwargs.update({'deep': deep})

    # iterate over each field and fork it!. nested calls will not commit,
    # until the recursion has finished
    for accessor in fields:
        _reset_field(reference, instance, accessor, **kwargs)

    # post-signal
    signals.post_reset.send(sender=reference.__class__, reference=reference,
        instance=instance, **kwargs)

    if commit:
        commit_model_object(instance)

    return instance
Exemple #2
0
    def test_deep_default_fields(self):
        author = Author()
        post = Post()
        blog = Blog()
        tag = Tag()

        self.assertEqual(utils._default_model_fields(author, deep=True),
                         set(['first_name', 'last_name', 'posts', 'blog']))

        self.assertEqual(utils._default_model_fields(post, deep=True),
                         set(['blog', 'authors', 'tags', 'title']))

        self.assertEqual(utils._default_model_fields(blog, deep=True),
                         set(['name', 'author', 'post_set']))

        self.assertEqual(utils._default_model_fields(tag, deep=True),
                         set(['name', 'post_set']))
Exemple #3
0
    def test_shallow_default_fields(self):
        author = Author()
        post = Post()
        blog = Blog()
        tag = Tag()

        self.assertEqual(utils._default_model_fields(author),
                         set(['first_name', 'last_name', 'posts']))

        self.assertEqual(utils._default_model_fields(post),
                         set(['blog', 'authors', 'tags', 'title']))

        self.assertEqual(utils._default_model_fields(blog),
                         set(['name', 'author']))

        self.assertEqual(utils._default_model_fields(tag),
                         set(['name', 'post_set']))
Exemple #4
0
    def test_deep_default_fields(self):
        author = Author()
        post = Post()
        blog = Blog()
        tag = Tag()

        self.assertEqual(utils._default_model_fields(author, deep=True),
            set(['first_name', 'last_name', 'posts', 'blog']))

        self.assertEqual(utils._default_model_fields(post, deep=True),
            set(['blog', 'authors', 'tags', 'title']))

        self.assertEqual(utils._default_model_fields(blog, deep=True),
            set(['name', 'author', 'post_set']))

        self.assertEqual(utils._default_model_fields(tag, deep=True),
            set(['name', 'post_set']))
Exemple #5
0
    def test_shallow_default_fields(self):
        author = Author()
        post = Post()
        blog = Blog()
        tag = Tag()

        self.assertEqual(utils._default_model_fields(author),
            set(['first_name', 'last_name', 'posts']))

        self.assertEqual(utils._default_model_fields(post),
            set(['blog', 'authors', 'tags', 'title']))

        self.assertEqual(utils._default_model_fields(blog),
            set(['name', 'author']))

        self.assertEqual(utils._default_model_fields(tag),
            set(['name', 'post_set']))
Exemple #6
0
def _diff(reference, instance, fields=None, exclude=('pk',), deep=False, **kwargs):
    if not fields:
        fields = utils._default_model_fields(reference, exclude, deep=deep)

    diff = {}
    for accessor in fields:
        diff.update(_diff_field(reference, instance, accessor, deep=deep, **kwargs))

    return diff
Exemple #7
0
def _diff(reference,
          instance,
          fields=None,
          exclude=('pk', ),
          deep=False,
          **kwargs):
    if not fields:
        fields = utils._default_model_fields(reference, exclude, deep=deep)

    diff = {}
    for accessor in fields:
        diff.update(
            _diff_field(reference, instance, accessor, deep=deep, **kwargs))

    return diff
Exemple #8
0
def _memoize_fork(reference, **kwargs):
    "Resets the specified instance relative to ``reference``"
    # popped so it does not get included in the config for the signal
    memo = kwargs.pop('memo', None)

    # for every call, keep track of the reference and the instance being
    # acted on. this is used for recursive calls to related objects. this
    # ensures relationships that follow back up the tree are caught and are
    # merely referenced rather than traversed again.
    if memo is None:
        memo = utils.Memo()
    elif memo.has(reference):
        return memo.get(reference)

    # initialize and memoize new instance
    instance = reference.__class__()
    instance._commits = utils.Commits(reference)    
    memo.add(reference, instance)

    # default configuration
    config = {
        'fields': None,
        'exclude': ['pk'],
        'deep': False,
        'commit': True,
    }

    # pop off and set any config params for signals
    for key in config.iterkeys():
        if kwargs.has_key(key):
            config[key] = kwargs.pop(key)

    # pre-signal
    signals.pre_fork.send(sender=reference.__class__, reference=reference,
        instance=instance, config=config, **kwargs)

    fields = config['fields']
    exclude = config['exclude']
    deep = config['deep']
    commit = config['commit']

    # no fields are defined, so get the default ones for shallow or deep
    if not fields:
        fields = utils._default_model_fields(reference, exclude=exclude, deep=deep)

    # add arguments for downstream use
    kwargs.update({'deep': deep})

    # iterate over each field and fork it!. nested calls will not commit,
    # until the recursion has finished
    for accessor in fields:
        _fork_field(reference, instance, accessor, memo=memo, **kwargs)

    # post-signal
    signals.post_fork.send(sender=reference.__class__, reference=reference,
        instance=instance, **kwargs)

    # as of now, this will only every be from a top-level call
    if commit:
        commit_model_object(instance, **kwargs)

    return instance
Exemple #9
0
def _memoize_fork(reference, **kwargs):
    "Resets the specified instance relative to ``reference``"
    # popped so it does not get included in the config for the signal
    memo = kwargs.pop('memo', None)

    # for every call, keep track of the reference and the instance being
    # acted on. this is used for recursive calls to related objects. this
    # ensures relationships that follow back up the tree are caught and are
    # merely referenced rather than traversed again.
    if memo is None:
        memo = utils.Memo()
    elif memo.has(reference):
        return memo.get(reference)

    # initialize and memoize new instance
    instance = reference.__class__()
    instance._commits = utils.Commits(reference)
    memo.add(reference, instance)

    # default configuration
    config = {
        'fields': None,
        'exclude': ['pk'],
        'deep': False,
        'commit': True,
    }

    # pop off and set any config params for signals
    for key in config.iterkeys():
        if kwargs.has_key(key):
            config[key] = kwargs.pop(key)

    # pre-signal
    signals.pre_fork.send(sender=reference.__class__,
                          reference=reference,
                          instance=instance,
                          config=config,
                          **kwargs)

    fields = config['fields']
    exclude = config['exclude']
    deep = config['deep']
    commit = config['commit']

    # no fields are defined, so get the default ones for shallow or deep
    if not fields:
        fields = utils._default_model_fields(reference,
                                             exclude=exclude,
                                             deep=deep)

    # add arguments for downstream use
    kwargs.update({'deep': deep})

    # iterate over each field and fork it!. nested calls will not commit,
    # until the recursion has finished
    for accessor in fields:
        _fork_field(reference, instance, accessor, memo=memo, **kwargs)

    # post-signal
    signals.post_fork.send(sender=reference.__class__,
                           reference=reference,
                           instance=instance,
                           **kwargs)

    # as of now, this will only every be from a top-level call
    if commit:
        commit_model_object(instance, **kwargs)

    return instance