Kaydet (Commit) 4668c142 authored tarafından Anssi Kääriäinen's avatar Anssi Kääriäinen

Made Model.__eq__ consider proxy models equivalent

Fixed #11892, fixed #16458, fixed #14492.
üst 40909826
......@@ -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)
......
......@@ -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``
--------------------
......
......@@ -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
==========================
......
......@@ -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):
......
......@@ -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)
......@@ -318,3 +318,8 @@ class ModelInheritanceTests(TestCase):
sql = query['sql']
if 'UPDATE' in sql:
self.assertEqual(expected_sql, sql)
def test_eq(self):
# Equality doesn't transfer in multitable inheritance.
self.assertNotEqual(Place(id=1), Restaurant(id=1))
self.assertNotEqual(Restaurant(id=1), Place(id=1))
......@@ -362,6 +362,9 @@ class ProxyModelTests(TestCase):
p = MyPerson.objects.get(pk=100)
self.assertEqual(p.name, 'Elvis Presley')
def test_eq(self):
self.assertEqual(MyPerson(id=100), Person(id=100))
class ProxyModelAdminTests(TestCase):
fixtures = ['myhorses']
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment