Loading django/db/models/base.py +3 −1 Original line number Diff line number Diff line Loading @@ -459,7 +459,9 @@ class Model(six.with_metaclass(ModelBase)): return '%s object' % self.__class__.__name__ def __eq__(self, other): return isinstance(other, self.__class__) and self._get_pk_val() == other._get_pk_val() return (isinstance(other, Model) and self._meta.concrete_model == other._meta.concrete_model and self._get_pk_val() == other._get_pk_val()) def __ne__(self, other): return not self.__eq__(other) Loading docs/ref/models/instances.txt +34 −0 Original line number Diff line number Diff line Loading @@ -494,6 +494,40 @@ using ``__str__()`` like this:: # first_name and last_name will be unicode strings. return force_bytes('%s %s' % (self.first_name, self.last_name)) ``__eq__`` ---------- .. method:: Model.__eq__() The equality method is defined such that instances with the same primary key value and the same concrete class are considered equal. The term concrete class means proxy model's first non-proxy parent or the class itself if it isn't a proxy class. For example:: form django.db import models class MyModel(models.Model): id = models.AutoField(primary_key=True) class MyProxyModel(MyModel): class Meta: proxy = True class MultitableInherited(MyModel): pass MyModel(id=1) == MyModel(id=1) MyModel(id=1) == MyProxyModel(id=1) MyModel(id=1) != MultitableInherited(id=1) MyModel(id=1) != MyModel(id=2) .. versionchanged:: 1.7 In previous versions only instances of the exact same class and same primary key value were considered equal. ``get_absolute_url`` -------------------- Loading docs/releases/1.7.txt +5 −0 Original line number Diff line number Diff line Loading @@ -194,6 +194,11 @@ Miscellaneous removes the ability for visitors to generate spurious HTTP 500 errors by requesting static files that don't exist or haven't been collected yet. * The :meth:`django.db.models.Model.__eq__` method is now defined in a way where instances of a proxy model and its base model are considered equal when primary keys match. Previously only instances of exact same class were considered equal on primary key match. Features deprecated in 1.7 ========================== Loading tests/basic/tests.py +4 −0 Original line number Diff line number Diff line Loading @@ -707,6 +707,10 @@ class ModelTest(TestCase): with self.assertRaises(ObjectDoesNotExist): SelfRef.objects.get(selfref=sr) def test_eq(self): self.assertNotEqual(Article(id=1), object()) self.assertNotEqual(object(), Article(id=1)) class ConcurrentSaveTests(TransactionTestCase): Loading tests/defer/tests.py +6 −0 Original line number Diff line number Diff line Loading @@ -183,3 +183,9 @@ class DeferTests(TestCase): with self.assertNumQueries(0): bc_deferred.id self.assertEqual(bc_deferred.pk, bc_deferred.id) def test_eq(self): s1 = Secondary.objects.create(first="x1", second="y1") s1_defer = Secondary.objects.only('pk').get(pk=s1.pk) self.assertEqual(s1, s1_defer) self.assertEqual(s1_defer, s1) Loading
django/db/models/base.py +3 −1 Original line number Diff line number Diff line Loading @@ -459,7 +459,9 @@ class Model(six.with_metaclass(ModelBase)): return '%s object' % self.__class__.__name__ def __eq__(self, other): return isinstance(other, self.__class__) and self._get_pk_val() == other._get_pk_val() return (isinstance(other, Model) and self._meta.concrete_model == other._meta.concrete_model and self._get_pk_val() == other._get_pk_val()) def __ne__(self, other): return not self.__eq__(other) Loading
docs/ref/models/instances.txt +34 −0 Original line number Diff line number Diff line Loading @@ -494,6 +494,40 @@ using ``__str__()`` like this:: # first_name and last_name will be unicode strings. return force_bytes('%s %s' % (self.first_name, self.last_name)) ``__eq__`` ---------- .. method:: Model.__eq__() The equality method is defined such that instances with the same primary key value and the same concrete class are considered equal. The term concrete class means proxy model's first non-proxy parent or the class itself if it isn't a proxy class. For example:: form django.db import models class MyModel(models.Model): id = models.AutoField(primary_key=True) class MyProxyModel(MyModel): class Meta: proxy = True class MultitableInherited(MyModel): pass MyModel(id=1) == MyModel(id=1) MyModel(id=1) == MyProxyModel(id=1) MyModel(id=1) != MultitableInherited(id=1) MyModel(id=1) != MyModel(id=2) .. versionchanged:: 1.7 In previous versions only instances of the exact same class and same primary key value were considered equal. ``get_absolute_url`` -------------------- Loading
docs/releases/1.7.txt +5 −0 Original line number Diff line number Diff line Loading @@ -194,6 +194,11 @@ Miscellaneous removes the ability for visitors to generate spurious HTTP 500 errors by requesting static files that don't exist or haven't been collected yet. * The :meth:`django.db.models.Model.__eq__` method is now defined in a way where instances of a proxy model and its base model are considered equal when primary keys match. Previously only instances of exact same class were considered equal on primary key match. Features deprecated in 1.7 ========================== Loading
tests/basic/tests.py +4 −0 Original line number Diff line number Diff line Loading @@ -707,6 +707,10 @@ class ModelTest(TestCase): with self.assertRaises(ObjectDoesNotExist): SelfRef.objects.get(selfref=sr) def test_eq(self): self.assertNotEqual(Article(id=1), object()) self.assertNotEqual(object(), Article(id=1)) class ConcurrentSaveTests(TransactionTestCase): Loading
tests/defer/tests.py +6 −0 Original line number Diff line number Diff line Loading @@ -183,3 +183,9 @@ class DeferTests(TestCase): with self.assertNumQueries(0): bc_deferred.id self.assertEqual(bc_deferred.pk, bc_deferred.id) def test_eq(self): s1 = Secondary.objects.create(first="x1", second="y1") s1_defer = Secondary.objects.only('pk').get(pk=s1.pk) self.assertEqual(s1, s1_defer) self.assertEqual(s1_defer, s1)