mirror of
https://github.com/django/django.git
synced 2025-01-03 06:55:47 +00:00
Fixed #32975 -- Fixed admin system check for inlines with foreign keys to proxy models.
This commit is contained in:
parent
b8824e8d17
commit
0e8be73812
@ -1009,9 +1009,17 @@ def _get_foreign_key(parent_model, model, fk_name=None, can_fail=False):
|
|||||||
fks_to_parent = [f for f in opts.fields if f.name == fk_name]
|
fks_to_parent = [f for f in opts.fields if f.name == fk_name]
|
||||||
if len(fks_to_parent) == 1:
|
if len(fks_to_parent) == 1:
|
||||||
fk = fks_to_parent[0]
|
fk = fks_to_parent[0]
|
||||||
if not isinstance(fk, ForeignKey) or \
|
parent_list = parent_model._meta.get_parent_list()
|
||||||
(fk.remote_field.model != parent_model and
|
if not isinstance(fk, ForeignKey) or (
|
||||||
fk.remote_field.model not in parent_model._meta.get_parent_list()):
|
# ForeignKey to proxy models.
|
||||||
|
fk.remote_field.model._meta.proxy and
|
||||||
|
fk.remote_field.model._meta.proxy_for_model not in parent_list
|
||||||
|
) or (
|
||||||
|
# ForeignKey to concrete models.
|
||||||
|
not fk.remote_field.model._meta.proxy and
|
||||||
|
fk.remote_field.model != parent_model and
|
||||||
|
fk.remote_field.model not in parent_list
|
||||||
|
):
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
"fk_name '%s' is not a ForeignKey to '%s'." % (fk_name, parent_model._meta.label)
|
"fk_name '%s' is not a ForeignKey to '%s'." % (fk_name, parent_model._meta.label)
|
||||||
)
|
)
|
||||||
@ -1021,11 +1029,15 @@ def _get_foreign_key(parent_model, model, fk_name=None, can_fail=False):
|
|||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
# Try to discover what the ForeignKey from model to parent_model is
|
# Try to discover what the ForeignKey from model to parent_model is
|
||||||
|
parent_list = parent_model._meta.get_parent_list()
|
||||||
fks_to_parent = [
|
fks_to_parent = [
|
||||||
f for f in opts.fields
|
f for f in opts.fields
|
||||||
if isinstance(f, ForeignKey) and (
|
if isinstance(f, ForeignKey) and (
|
||||||
f.remote_field.model == parent_model or
|
f.remote_field.model == parent_model or
|
||||||
f.remote_field.model in parent_model._meta.get_parent_list()
|
f.remote_field.model in parent_list or (
|
||||||
|
f.remote_field.model._meta.proxy and
|
||||||
|
f.remote_field.model._meta.proxy_for_model in parent_list
|
||||||
|
)
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
if len(fks_to_parent) == 1:
|
if len(fks_to_parent) == 1:
|
||||||
|
@ -4,7 +4,7 @@ from django.contrib.admin import BooleanFieldListFilter, SimpleListFilter
|
|||||||
from django.contrib.admin.options import VERTICAL, ModelAdmin, TabularInline
|
from django.contrib.admin.options import VERTICAL, ModelAdmin, TabularInline
|
||||||
from django.contrib.admin.sites import AdminSite
|
from django.contrib.admin.sites import AdminSite
|
||||||
from django.core.checks import Error
|
from django.core.checks import Error
|
||||||
from django.db.models import F, Field, Model
|
from django.db.models import CASCADE, F, Field, ForeignKey, Model
|
||||||
from django.db.models.functions import Upper
|
from django.db.models.functions import Upper
|
||||||
from django.forms.models import BaseModelFormSet
|
from django.forms.models import BaseModelFormSet
|
||||||
from django.test import SimpleTestCase
|
from django.test import SimpleTestCase
|
||||||
@ -1121,6 +1121,33 @@ class FkNameCheckTests(CheckTestCase):
|
|||||||
|
|
||||||
self.assertIsValid(TestModelAdmin, ValidationTestModel)
|
self.assertIsValid(TestModelAdmin, ValidationTestModel)
|
||||||
|
|
||||||
|
def test_proxy_model_parent(self):
|
||||||
|
class Parent(Model):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class ProxyChild(Parent):
|
||||||
|
class Meta:
|
||||||
|
proxy = True
|
||||||
|
|
||||||
|
class ProxyProxyChild(ProxyChild):
|
||||||
|
class Meta:
|
||||||
|
proxy = True
|
||||||
|
|
||||||
|
class Related(Model):
|
||||||
|
proxy_child = ForeignKey(ProxyChild, on_delete=CASCADE)
|
||||||
|
|
||||||
|
class InlineFkName(admin.TabularInline):
|
||||||
|
model = Related
|
||||||
|
fk_name = 'proxy_child'
|
||||||
|
|
||||||
|
class InlineNoFkName(admin.TabularInline):
|
||||||
|
model = Related
|
||||||
|
|
||||||
|
class ProxyProxyChildAdminFkName(admin.ModelAdmin):
|
||||||
|
inlines = [InlineFkName, InlineNoFkName]
|
||||||
|
|
||||||
|
self.assertIsValid(ProxyProxyChildAdminFkName, ProxyProxyChild)
|
||||||
|
|
||||||
|
|
||||||
class ExtraCheckTests(CheckTestCase):
|
class ExtraCheckTests(CheckTestCase):
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user