Fixed #11560 -- Allowed proxy model multiple-inheritance from the same concrete base model.
This commit is contained in:
parent
2e0cd26ffb
commit
49f95cc0a0
|
@ -177,10 +177,10 @@ class ModelBase(type):
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
continue
|
continue
|
||||||
if base is not None:
|
if base is None:
|
||||||
raise TypeError("Proxy model '%s' has more than one non-abstract model base class." % name)
|
|
||||||
else:
|
|
||||||
base = parent
|
base = parent
|
||||||
|
elif parent._meta.concrete_model is not base._meta.concrete_model:
|
||||||
|
raise TypeError("Proxy model '%s' has more than one non-abstract model base class." % name)
|
||||||
if base is None:
|
if base is None:
|
||||||
raise TypeError("Proxy model '%s' has no non-abstract model base class." % name)
|
raise TypeError("Proxy model '%s' has no non-abstract model base class." % name)
|
||||||
new_class._meta.setup_proxy(base)
|
new_class._meta.setup_proxy(base)
|
||||||
|
|
|
@ -359,6 +359,9 @@ Models
|
||||||
|
|
||||||
* Added the :class:`~django.db.models.functions.Cast` database function.
|
* Added the :class:`~django.db.models.functions.Cast` database function.
|
||||||
|
|
||||||
|
* A proxy model may now inherit multiple proxy models that share a common
|
||||||
|
non-abstract parent class.
|
||||||
|
|
||||||
Requests and Responses
|
Requests and Responses
|
||||||
~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|
|
@ -1230,7 +1230,13 @@ A proxy model must inherit from exactly one non-abstract model class. You
|
||||||
can't inherit from multiple non-abstract models as the proxy model doesn't
|
can't inherit from multiple non-abstract models as the proxy model doesn't
|
||||||
provide any connection between the rows in the different database tables. A
|
provide any connection between the rows in the different database tables. A
|
||||||
proxy model can inherit from any number of abstract model classes, providing
|
proxy model can inherit from any number of abstract model classes, providing
|
||||||
they do *not* define any model fields.
|
they do *not* define any model fields. A proxy model may also inherit from any
|
||||||
|
number of proxy models that share a common non-abstract parent class.
|
||||||
|
|
||||||
|
.. versionchanged:: 1.10
|
||||||
|
|
||||||
|
In earlier versions, a proxy model couldn't inherit more than one proxy
|
||||||
|
model that shared the same parent class.
|
||||||
|
|
||||||
Proxy model managers
|
Proxy model managers
|
||||||
~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
|
@ -110,10 +110,20 @@ class UserProxy(User):
|
||||||
proxy = True
|
proxy = True
|
||||||
|
|
||||||
|
|
||||||
|
class AnotherUserProxy(User):
|
||||||
|
class Meta:
|
||||||
|
proxy = True
|
||||||
|
|
||||||
|
|
||||||
class UserProxyProxy(UserProxy):
|
class UserProxyProxy(UserProxy):
|
||||||
class Meta:
|
class Meta:
|
||||||
proxy = True
|
proxy = True
|
||||||
|
|
||||||
|
|
||||||
|
class MultiUserProxy(UserProxy, AnotherUserProxy):
|
||||||
|
class Meta:
|
||||||
|
proxy = True
|
||||||
|
|
||||||
# We can still use `select_related()` to include related models in our querysets.
|
# We can still use `select_related()` to include related models in our querysets.
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -13,9 +13,9 @@ from django.urls import reverse
|
||||||
from .admin import admin as force_admin_model_registration # NOQA
|
from .admin import admin as force_admin_model_registration # NOQA
|
||||||
from .models import (
|
from .models import (
|
||||||
Abstract, BaseUser, Bug, Country, Improvement, Issue, LowerStatusPerson,
|
Abstract, BaseUser, Bug, Country, Improvement, Issue, LowerStatusPerson,
|
||||||
MyPerson, MyPersonProxy, OtherPerson, Person, ProxyBug, ProxyImprovement,
|
MultiUserProxy, MyPerson, MyPersonProxy, OtherPerson, Person, ProxyBug,
|
||||||
ProxyProxyBug, ProxyTrackerUser, State, StateProxy, StatusPerson,
|
ProxyImprovement, ProxyProxyBug, ProxyTrackerUser, State, StateProxy,
|
||||||
TrackerUser, User, UserProxy, UserProxyProxy,
|
StatusPerson, TrackerUser, User, UserProxy, UserProxyProxy,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -246,7 +246,7 @@ class ProxyModelTests(TestCase):
|
||||||
ctype = ContentType.objects.get_for_model
|
ctype = ContentType.objects.get_for_model
|
||||||
self.assertIs(ctype(Person), ctype(OtherPerson))
|
self.assertIs(ctype(Person), ctype(OtherPerson))
|
||||||
|
|
||||||
def test_user_userproxy_userproxyproxy(self):
|
def test_user_proxy_models(self):
|
||||||
User.objects.create(name='Bruce')
|
User.objects.create(name='Bruce')
|
||||||
|
|
||||||
resp = [u.name for u in User.objects.all()]
|
resp = [u.name for u in User.objects.all()]
|
||||||
|
@ -258,6 +258,8 @@ class ProxyModelTests(TestCase):
|
||||||
resp = [u.name for u in UserProxyProxy.objects.all()]
|
resp = [u.name for u in UserProxyProxy.objects.all()]
|
||||||
self.assertEqual(resp, ['Bruce'])
|
self.assertEqual(resp, ['Bruce'])
|
||||||
|
|
||||||
|
self.assertEqual([u.name for u in MultiUserProxy.objects.all()], ['Bruce'])
|
||||||
|
|
||||||
def test_proxy_for_model(self):
|
def test_proxy_for_model(self):
|
||||||
self.assertEqual(UserProxy, UserProxyProxy._meta.proxy_for_model)
|
self.assertEqual(UserProxy, UserProxyProxy._meta.proxy_for_model)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue