예제 #1
0
def _fork_field(reference, instance, accessor, **kwargs):
    """Creates a copy of the reference value for the defined ``accessor``
    (field). For deep forks, each related object is related objects must
    be created first prior to being recursed.
    """
    value, field, direct, m2m = utils._get_field_value(reference, accessor)

    if value is None:
        return

    # recursive calls cannot be saved until everything has been traversed..
    kwargs['commit'] = False

    if isinstance(field, models.OneToOneField):
        return _fork_one2one(instance, value, field, direct,
            accessor, **kwargs)

    if isinstance(field, models.ForeignKey):
        return _fork_foreignkey(instance, value, field, direct,
            accessor, **kwargs)

    if isinstance(field, models.ManyToManyField):
        return _fork_many2many(instance, value, field, direct,
            accessor, **kwargs)

    # non-relational field, perform a deepcopy to ensure no mutable nonsense
    setattr(instance, accessor, deepcopy(value))
예제 #2
0
def _fork_field(reference, instance, accessor, **kwargs):
    """Creates a copy of the reference value for the defined ``accessor``
    (field). For deep forks, each related object is related objects must
    be created first prior to being recursed.
    """
    value, field, direct, m2m = utils._get_field_value(reference, accessor)

    if value is None:
        return

    # recursive calls cannot be saved until everything has been traversed..
    kwargs['commit'] = False

    if isinstance(field, models.OneToOneField):
        return _fork_one2one(instance, value, field, direct, accessor,
                             **kwargs)

    if isinstance(field, models.ForeignKey):
        return _fork_foreignkey(instance, value, field, direct, accessor,
                                **kwargs)

    if isinstance(field, models.ManyToManyField):
        return _fork_many2many(instance, value, field, direct, accessor,
                               **kwargs)

    # non-relational field, perform a deepcopy to ensure no mutable nonsense
    setattr(instance, accessor, deepcopy(value))
예제 #3
0
def _reset_foreignkey(instance, refvalue, field, direct, accessor, deep, **kwargs):
    value = utils._get_field_value(instance, accessor)[0]
    if refvalue and value and deep:
        _memoize_reset(refvalue, value, deep=deep, **kwargs)
    # for shallow or when value is None, use the reference value
    elif not value:
        value = refvalue

    instance._commits.defer(accessor, value, direct=direct)
예제 #4
0
def _diff_field(reference, instance, accessor, deep, **kwargs):
    "Returns the field's value of ``instance`` if different form ``reference``."
    val1, field, direct, m2m = utils._get_field_value(reference, accessor)
    val2 = utils._get_field_value(instance, accessor)[0]

    # get the diff for m2m or reverse foreign keys
    if m2m or not direct and not isinstance(field, models.OneToOneField):
        if _diff_queryset(reference, val1, val2) is not None:
            return {accessor: list(val2)}
    # direct foreign keys and one-to-one
    elif deep and (isinstance(field, models.ForeignKey) or isinstance(field, models.OneToOneField)):
        if val1 and val2:
            diff = diff_model_object(val1, val2, **kwargs)
            if diff:
                return {accessor: diff}
    elif val1 != val2:
        return {accessor: val2}
    return {}
예제 #5
0
def _diff_field(reference, instance, accessor, deep, **kwargs):
    "Returns the field's value of ``instance`` if different form ``reference``."
    val1, field, direct, m2m = utils._get_field_value(reference, accessor)
    val2 = utils._get_field_value(instance, accessor)[0]

    # get the diff for m2m or reverse foreign keys
    if m2m or not direct and not isinstance(field, models.OneToOneField):
        if _diff_queryset(reference, val1, val2) is not None:
            return {accessor: list(val2)}
    # direct foreign keys and one-to-one
    elif deep and (isinstance(field, models.ForeignKey)
                   or isinstance(field, models.OneToOneField)):
        if val1 and val2:
            diff = diff_model_object(val1, val2, **kwargs)
            if diff:
                return {accessor: diff}
    elif val1 != val2:
        return {accessor: val2}
    return {}
예제 #6
0
    def test_deep_signal(self):
        # before signal is connected.. complete deep fork
        fork = self.author.fork(commit=False, deep=True)

        post0 = utils._get_field_value(fork, 'posts')[0][0]
        self.assertEqual(post0.title, 'Django Tip: Descriptors')

        blog0 = utils._get_field_value(post0, 'blog')[0]
        self.assertTrue(isinstance(blog0, Blog))

        # connect the post signal to limit the fields..
        signals.pre_fork.connect(post_config, sender=Post)

        fork = self.author.fork(commit=False, deep=True)

        post0 = utils._get_field_value(fork, 'posts')[0][0]
        self.assertEqual(post0.title, 'Django Tip: Descriptors')

        blog0 = utils._get_field_value(post0, 'blog')[0]
        # odd usage of _get_field_value, but it works..
        self.assertEqual(blog0, None)

        signals.pre_fork.disconnect(post_config, sender=Post)
예제 #7
0
    def test_deep_signal(self):
        # before signal is connected.. complete deep fork
        fork = self.author.fork(commit=False, deep=True)

        post0 = utils._get_field_value(fork, 'posts')[0][0]
        self.assertEqual(post0.title, 'Django Tip: Descriptors')

        blog0 = utils._get_field_value(post0, 'blog')[0]
        self.assertTrue(isinstance(blog0, Blog))

        # connect the post signal to limit the fields..
        signals.pre_fork.connect(post_config, sender=Post)

        fork = self.author.fork(commit=False, deep=True)

        post0 = utils._get_field_value(fork, 'posts')[0][0]
        self.assertEqual(post0.title, 'Django Tip: Descriptors')

        blog0 = utils._get_field_value(post0, 'blog')[0]
        # odd usage of _get_field_value, but it works..
        self.assertEqual(blog0, None)

        signals.pre_fork.disconnect(post_config)
예제 #8
0
    def test_field_value(self):
        self.assertEqual(utils._get_field_value(self.author, 'first_name')[0], 'Byron')
        # returns a queryset, compare the querysets
        author_posts = utils._get_field_value(self.author, 'posts')[0]
        self.assertEqual(diff._diff_queryset(self.author, author_posts, Post.objects.all()), None)
        # one-to-ones are simple, the instance if returned directly
        self.assertEqual(utils._get_field_value(self.author, 'blog')[0], self.blog)

        # direct foreign key, same as one-to-one
        self.assertEqual(utils._get_field_value(self.post, 'blog')[0], self.blog)
        # direct many-to-many, behaves the same as reverse foreign keys
        post_authors = utils._get_field_value(self.post, 'authors')[0]
        self.assertEqual(diff._diff_queryset(self.post, post_authors, Author.objects.all()), None)
        # direct many-to-many, behaves the same as reverse foreign keys
        post_tags = utils._get_field_value(self.post, 'tags')[0]
        self.assertEqual(diff._diff_queryset(self.post, post_tags, Tag.objects.all()), None)

        self.assertEqual(utils._get_field_value(self.blog, 'author')[0], self.author)
        blog_posts = utils._get_field_value(self.blog, 'post_set')[0]
        self.assertEqual(diff._diff_queryset(self.blog, blog_posts, Post.objects.all()), None)

        tag_posts = utils._get_field_value(self.tag, 'post_set')[0]
        self.assertEqual(diff._diff_queryset(self.blog, tag_posts, Post.objects.all()), None)
예제 #9
0
    def test_field_value(self):
        self.assertEqual(
            utils._get_field_value(self.author, 'first_name')[0], 'Byron')
        # returns a queryset, compare the querysets
        author_posts = utils._get_field_value(self.author, 'posts')[0]
        self.assertEqual(
            diff._diff_queryset(self.author, author_posts, Post.objects.all()),
            None)
        # one-to-ones are simple, the instance if returned directly
        self.assertEqual(
            utils._get_field_value(self.author, 'blog')[0], self.blog)

        # direct foreign key, same as one-to-one
        self.assertEqual(
            utils._get_field_value(self.post, 'blog')[0], self.blog)
        # direct many-to-many, behaves the same as reverse foreign keys
        post_authors = utils._get_field_value(self.post, 'authors')[0]
        self.assertEqual(
            diff._diff_queryset(self.post, post_authors, Author.objects.all()),
            None)
        # direct many-to-many, behaves the same as reverse foreign keys
        post_tags = utils._get_field_value(self.post, 'tags')[0]
        self.assertEqual(
            diff._diff_queryset(self.post, post_tags, Tag.objects.all()), None)

        self.assertEqual(
            utils._get_field_value(self.blog, 'author')[0], self.author)
        blog_posts = utils._get_field_value(self.blog, 'post_set')[0]
        self.assertEqual(
            diff._diff_queryset(self.blog, blog_posts, Post.objects.all()),
            None)

        tag_posts = utils._get_field_value(self.tag, 'post_set')[0]
        self.assertEqual(
            diff._diff_queryset(self.blog, tag_posts, Post.objects.all()),
            None)
예제 #10
0
def _reset_field(reference, instance, accessor, **kwargs):
    """Creates a copy of the reference value for the defined ``accessor``
    (field). For deep forks, each related object is related objects must
    be created first prior to being recursed.
    """
    value, field, direct, m2m = utils._get_field_value(reference, accessor)

    # explicitly block reverse and m2m relationships..
    if not direct or m2m:
        return

    kwargs['commit'] = False

    if isinstance(field, models.OneToOneField):
        return _reset_one2one(instance, value, field, direct,
            accessor, **kwargs)

    if isinstance(field, models.ForeignKey):
        return _reset_foreignkey(instance, value, field, direct,
            accessor, **kwargs)

    # non-relational field, perform a deepcopy to ensure no mutable nonsense
    setattr(instance, accessor, deepcopy(value))
예제 #11
0
def _reset_one2one(instance, refvalue, field, direct, accessor, deep, **kwargs):
    value = utils._get_field_value(instance, accessor)[0]
    if refvalue and value and deep:
        _memoize_reset(refvalue, value, deep=deep, **kwargs)
        instance._commits.defer(accessor, value, direct=direct)