예제 #1
0
def diff(object1, object2):
    """
    Compares two objects (such as model instances) and returns an object that
    can be used to render the differences between the two objects.

    Example::

        >>> m1 = Person(name="Philip")
        >>> m2 = Person(name="Phillip")
        >>> diff(m1, m2).as_dict()
        {'name': [{'equal': 'Phil'}, {'inserted': 'l'}, {'equal': 'ip'}]}
        >>> diff(m1, m2).as_html()
        u('<tr>'
            '<td colspan="2">name</td>'
          '</tr>
          '<tr>'
          '<td colspan="2">'
            '<span class="diff_equal">Phil</span>'
            '<ins>l</ins>'
            '<span class="diff_equal">ip</span>'
          '</td>
          '</tr>')

    This can work with versioned models, e.g.::

        >> diff(m1.history.as_of(version=2),
        >>      m2.history.as_of(version=3)).as_html()
        u('<tr>'
            '<td colspan="2">name</td>'
          '</tr>
          '<tr>'
          '<td colspan="2">'
            '<span class="diff_equal">Phil</span>'
            '<ins>l</ins>'
            '<span class="diff_equal">ip!</span>'
          '</td>
          '</tr>')

    Returns:
        An object that can be used to display differences.  Object will be
        either BaseModelDiff or a subclass.

    Raises:
        DiffUtilNotFound: If there's no registered or inferred diff for
        the objects.
    """
    if is_historical_instance(object1):
        object1 = object1.history_info._object
    if is_historical_instance(object2):
        object2 = object2.history_info._object
    diff_util = registry.get_diff_util(object1.__class__)
    return diff_util(object1, object2)
예제 #2
0
def diff(object1, object2):
    """
    Compares two objects (such as model instances) and returns an object that
    can be used to render the differences between the two objects.

    Example::

        >>> m1 = Person(name="Philip")
        >>> m2 = Person(name="Phillip")
        >>> diff(m1, m2).as_dict()
        {'name': [{'equal': 'Phil'}, {'inserted': 'l'}, {'equal': 'ip'}]}
        >>> diff(m1, m2).as_html()
        u('<tr>'
            '<td colspan="2">name</td>'
          '</tr>
          '<tr>'
          '<td colspan="2">'
            '<span class="diff_equal">Phil</span>'
            '<ins>l</ins>'
            '<span class="diff_equal">ip</span>'
          '</td>
          '</tr>')

    This can work with versioned models, e.g.::

        >> diff(m1.history.as_of(version=2),
        >>      m2.history.as_of(version=3)).as_html()
        u('<tr>'
            '<td colspan="2">name</td>'
          '</tr>
          '<tr>'
          '<td colspan="2">'
            '<span class="diff_equal">Phil</span>'
            '<ins>l</ins>'
            '<span class="diff_equal">ip!</span>'
          '</td>
          '</tr>')

    Returns:
        An object that can be used to display differences.  Object will be
        either BaseModelDiff or a subclass.

    Raises:
        DiffUtilNotFound: If there's no registered or inferred diff for
        the objects.
    """
    if is_historical_instance(object1): 
        object1 = object1.history_info._object
    if is_historical_instance(object2): 
        object2 = object2.history_info._object
    diff_util = registry.get_diff_util(object1.__class__)
    return diff_util(object1, object2)
예제 #3
0
    def get_diff(self):
        """
        Returns:
            A dictionary that contains all field diffs, indexed by field name.
        """
        if self._diff is not None:
            return self._diff
        diff = {}
        diff_utils = {}

        if self.fields:
            diff_fields = self.fields
        else:
            diff_fields = [f.name for f in self.model_class._meta.fields]

        for name in diff_fields:
            if isinstance(name, basestring):
                field = self.model_class._meta.get_field(name)
                if isinstance(field, (models.AutoField, )):
                    continue
                diff_utils[name] = registry.get_diff_util(field.__class__)
            else:
                diff_utils[name[0]] = name[1]

        for field_name, diff_class in diff_utils.items():
            if field_name in self.excludes:
                continue

            obj1 = getattr(self.model1, field_name)
            obj2 = getattr(self.model2, field_name)
            is_model_diff = issubclass(diff_class, BaseModelDiff)

            if is_model_diff:
                # Use the non-versioned class to do the diff on the
                # versioned fields.
                if is_historical_instance(obj1):
                    base_class = obj1.version_info._object.__class__
                else:
                    base_class = obj1.__class__
                diff[field_name] = diff_class(obj1,
                                              obj2,
                                              model_class=base_class,
                                              context=self.context)
            else:
                diff[field_name] = diff_class(obj1, obj2, context=self.context)

        self._diff = diff
        return diff
예제 #4
0
    def get_diff(self):
        """
        Returns:
            A dictionary that contains all field diffs, indexed by field name.
        """
        if self._diff is not None:
            return self._diff
        diff = {}
        diff_utils = {}

        if self.fields:
            diff_fields = self.fields
        else:
            diff_fields = [f.name for f in self.model_class._meta.fields]

        for name in diff_fields:
            if isinstance(name, basestring):
                field = self.model_class._meta.get_field(name)
                if isinstance(field, (models.AutoField,)):
                    continue
                diff_utils[name] = registry.get_diff_util(field.__class__)
            else:
                diff_utils[name[0]] = name[1]

        for field_name, diff_class in diff_utils.items():
            if field_name in self.excludes:
                continue

            obj1 = getattr(self.model1, field_name)
            obj2 = getattr(self.model2, field_name)
            is_model_diff = issubclass(diff_class, BaseModelDiff)

            if is_model_diff:
                # Use the non-versioned class to do the diff on the
                # versioned fields.
                if is_historical_instance(obj1):
                    base_class = obj1.history_info._object.__class__
                else:
                    base_class = obj1.__class__
                diff[field_name] = diff_class(obj1, obj2,
                    model_class=base_class)
            else:
                diff[field_name] = diff_class(obj1, obj2)

        self._diff = diff
        return diff