Ticket #16458: 16458.2.diff

File 16458.2.diff, 5.0 KB (added by Anssi Kääriäinen, 8 years ago)
  • django/db/models/base.py

    diff --git a/django/db/models/base.py b/django/db/models/base.py
    index 71fd1f7..feaceee 100644
    a b class Model(object): 
    382382        return '%s object' % self.__class__.__name__
    383383
    384384    def __eq__(self, other):
    385         return isinstance(other, self.__class__) and self._get_pk_val() == other._get_pk_val()
     385        return isinstance(other, Model) and \
     386               self._meta.proxy_for_model == other._meta.proxy_for_model and \
     387               self._get_pk_val() == other._get_pk_val()
    386388
    387389    def __ne__(self, other):
    388390        return not self.__eq__(other)
  • django/db/models/options.py

    diff --git a/django/db/models/options.py b/django/db/models/options.py
    index 6f0f406..00a5586 100644
    a b class Options(object): 
    6464        self.object_name = cls.__name__
    6565        self.module_name = self.object_name.lower()
    6666        self.verbose_name = get_verbose_name(self.object_name)
     67        # Note: for convenience we set that every concrete class and abstract class
     68        # is proxy of itself. This helps in __eq__ checks for example.
     69        self.proxy_for_model = cls
    6770
    6871        # Next, apply any overridden values from 'class Meta'.
    6972        if self.meta:
  • docs/topics/db/models.txt

    diff --git a/docs/topics/db/models.txt b/docs/topics/db/models.txt
    index 0e18205..ec3324d 100644
    a b There are three styles of inheritance that are possible in Django. 
    795795    without changing the models fields in any way, you can use
    796796    :ref:`proxy-models`.
    797797
     798A note about model instance equality operator
     799~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     800
     801When comparing the equality of model instances, Django uses the following
     802rules. Two instances are considered equal if:
     803
     804  1. The primary keys are equal. Note that if both instances have primary key value of None, they are considered equal.
     805  2. The instances are of same class. For this rule, proxy models are considered instances of the class they are proxying. Multi-table inheriting instance is not considered to be of same class with its base class.
     806
    798807.. _abstract-base-classes:
    799808
    800809Abstract base classes
  • tests/modeltests/defer/tests.py

    diff --git a/tests/modeltests/defer/tests.py b/tests/modeltests/defer/tests.py
    index 5f6c53d..9cf32ee 100644
    a b class DeferTests(TestCase): 
    2323        p1 = Primary.objects.create(name="p1", value="xx", related=s1)
    2424
    2525        qs = Primary.objects.all()
    26 
    2726        self.assert_delayed(qs.defer("name")[0], 1)
    2827        self.assert_delayed(qs.only("name")[0], 2)
    2928        self.assert_delayed(qs.defer("related__first")[0], 0)
     29       
     30        # deferred instances are equal to their non-deferred counterpart
     31        deferred_p1 = qs.defer("name")[0]
     32        self.assertTrue(deferred_p1==p1)
     33        # The __eq__ operator is symmetric as well as the == operator
     34        self.assertTrue(p1==deferred_p1)
     35        self.assertTrue(deferred_p1.__eq__(p1))
     36        self.assertTrue(p1.__eq__(deferred_p1))
     37
    3038
    3139        obj = qs.select_related().only("related__first")[0]
    3240        self.assert_delayed(obj, 2)
  • tests/modeltests/model_inheritance/tests.py

    diff --git a/tests/modeltests/model_inheritance/tests.py b/tests/modeltests/model_inheritance/tests.py
    index 334297a..1b19dcb 100644
    a b class ModelInheritanceTests(TestCase): 
    6969            StudentWorker.objects.get, pk__lt=sw2.pk + 100
    7070        )
    7171
     72        # A multi-table inherited instance is never cosidered equal to
     73        # its base class instances.
     74        w = Worker(pk=1)
     75        sw = StudentWorker(pk=1)
     76        self.assertFalse(w==sw)
     77        # The __eq__ operator is symmetric as well as the '==' operator
     78        self.assertFalse(sw==w)
     79        self.assertFalse(w.__eq__(sw))
     80        self.assertFalse(sw.__eq__(w))
     81
    7282    def test_multiple_table(self):
    7383        post = Post.objects.create(title="Lorem Ipsum")
    7484        # The Post model has distinct accessors for the Comment and Link models.
  • tests/modeltests/proxy_models/tests.py

    diff --git a/tests/modeltests/proxy_models/tests.py b/tests/modeltests/proxy_models/tests.py
    index 0a46a25..a4c7d40 100644
    a b class ProxyModelTests(TestCase): 
    4545        self.assertEqual(MyPerson.objects.get(name="Foo McBar").id, person.id)
    4646        self.assertFalse(MyPerson.objects.get(id=person.id).has_special_name())
    4747
     48    def test_proxy_eq(self):
     49        """
     50        Proxied models are considered equal to their concrete base class.
     51        """
     52        p = Person(pk=1)
     53        mp = MyPerson(pk=1)
     54        self.assertTrue(p==mp)
     55        # the __eq__ operator is symmetric as well as the == operator
     56        self.assertTrue(mp==p)
     57        self.assertTrue(p.__eq__(mp))
     58        self.assertTrue(mp.__eq__(p))
     59
    4860    def test_no_proxy(self):
    4961        """
    5062        Person is not proxied by StatusPerson subclass.
Back to Top