Kaydet (Commit) 724e6008 authored tarafından Craig de Stigter's avatar Craig de Stigter Kaydeden (comit) Tim Graham

[1.7.x] Fixed #22690 -- Added a check for proxy models containing fields.

Removed the FieldError raised by ModelBase.__new__ in this case.

Backport of ce993efd from master
üst 160fd6c7
...@@ -193,9 +193,6 @@ class ModelBase(type): ...@@ -193,9 +193,6 @@ class ModelBase(type):
base = parent base = parent
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)
if (new_class._meta.local_fields or
new_class._meta.local_many_to_many):
raise FieldError("Proxy model '%s' contains model fields." % name)
new_class._meta.setup_proxy(base) new_class._meta.setup_proxy(base)
new_class._meta.concrete_model = base._meta.concrete_model new_class._meta.concrete_model = base._meta.concrete_model
else: else:
...@@ -1044,6 +1041,7 @@ class Model(six.with_metaclass(ModelBase)): ...@@ -1044,6 +1041,7 @@ class Model(six.with_metaclass(ModelBase)):
def check(cls, **kwargs): def check(cls, **kwargs):
errors = [] errors = []
errors.extend(cls._check_swappable()) errors.extend(cls._check_swappable())
errors.extend(cls._check_model())
errors.extend(cls._check_managers(**kwargs)) errors.extend(cls._check_managers(**kwargs))
if not cls._meta.swapped: if not cls._meta.swapped:
errors.extend(cls._check_fields(**kwargs)) errors.extend(cls._check_fields(**kwargs))
...@@ -1091,6 +1089,21 @@ class Model(six.with_metaclass(ModelBase)): ...@@ -1091,6 +1089,21 @@ class Model(six.with_metaclass(ModelBase)):
) )
return errors return errors
@classmethod
def _check_model(cls):
errors = []
if cls._meta.proxy:
if cls._meta.local_fields or cls._meta.local_many_to_many:
errors.append(
checks.Error(
"Proxy model '%s' contains model fields." % cls.__name__,
hint=None,
obj=None,
id='models.E017',
)
)
return errors
@classmethod @classmethod
def _check_managers(cls, **kwargs): def _check_managers(cls, **kwargs):
""" Perform all manager checks. """ """ Perform all manager checks. """
......
...@@ -44,6 +44,7 @@ Models ...@@ -44,6 +44,7 @@ Models
* **models.E013**: ``index_together/unique_together`` refers to a ManyToManyField ``<field name>``, but ManyToManyFields are not supported for that option. * **models.E013**: ``index_together/unique_together`` refers to a ManyToManyField ``<field name>``, but ManyToManyFields are not supported for that option.
* **models.E014**: ``ordering`` must be a tuple or list (even if you want to order by only one field). * **models.E014**: ``ordering`` must be a tuple or list (even if you want to order by only one field).
* **models.E015**: ``ordering`` refers to the non-existent field ``<field name>``. * **models.E015**: ``ordering`` refers to the non-existent field ``<field name>``.
* **models.E017**: Proxy model ``<model>`` contains model fields.
Fields Fields
~~~~~~ ~~~~~~
......
...@@ -4,7 +4,7 @@ from django.apps import apps ...@@ -4,7 +4,7 @@ from django.apps import apps
from django.contrib import admin from django.contrib import admin
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from django.core import management from django.core import management
from django.core.exceptions import FieldError from django.core import checks
from django.db import models, DEFAULT_DB_ALIAS from django.db import models, DEFAULT_DB_ALIAS
from django.db.models import signals from django.db.models import signals
from django.test import TestCase, override_settings from django.test import TestCase, override_settings
...@@ -143,13 +143,25 @@ class ProxyModelTests(TestCase): ...@@ -143,13 +143,25 @@ class ProxyModelTests(TestCase):
self.assertRaises(TypeError, build_no_base_classes) self.assertRaises(TypeError, build_no_base_classes)
def test_new_fields(self): def test_new_fields(self):
def build_new_fields(): class NoNewFields(Person):
class NoNewFields(Person): newfield = models.BooleanField()
newfield = models.BooleanField()
class Meta:
class Meta: proxy = True
proxy = True # don't register this model in the app_cache for the current app,
self.assertRaises(FieldError, build_new_fields) # otherwise the check fails when other tests are being run.
app_label = 'no_such_app'
errors = NoNewFields.check()
expected = [
checks.Error(
"Proxy model 'NoNewFields' contains model fields.",
hint=None,
obj=None,
id='models.E017',
)
]
self.assertEqual(errors, expected)
@override_settings(TEST_SWAPPABLE_MODEL='proxy_models.AlternateModel') @override_settings(TEST_SWAPPABLE_MODEL='proxy_models.AlternateModel')
def test_swappable(self): def test_swappable(self):
......
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