Fixed #28695 -- Allowed models to use __init_subclass__().

This commit is contained in:
k 2017-10-13 21:29:00 -04:00 committed by Tim Graham
parent 9dd405973c
commit 399a8db33b
3 changed files with 22 additions and 3 deletions

View File

@ -60,7 +60,7 @@ def subclass_exception(name, bases, module, attached_to):
class ModelBase(type): class ModelBase(type):
"""Metaclass for all models.""" """Metaclass for all models."""
def __new__(cls, name, bases, attrs): def __new__(cls, name, bases, attrs, **kwargs):
super_new = super().__new__ super_new = super().__new__
# Also ensure initialization is only performed for subclasses of Model # Also ensure initialization is only performed for subclasses of Model
@ -75,7 +75,7 @@ class ModelBase(type):
classcell = attrs.pop('__classcell__', None) classcell = attrs.pop('__classcell__', None)
if classcell is not None: if classcell is not None:
new_attrs['__classcell__'] = classcell new_attrs['__classcell__'] = classcell
new_class = super_new(cls, name, bases, new_attrs) new_class = super_new(cls, name, bases, new_attrs, **kwargs)
attr_meta = attrs.pop('Meta', None) attr_meta = attrs.pop('Meta', None)
abstract = getattr(attr_meta, 'abstract', False) abstract = getattr(attr_meta, 'abstract', False)
if not attr_meta: if not attr_meta:

View File

@ -153,7 +153,7 @@ Migrations
Models Models
~~~~~~ ~~~~~~
* ... * Models can now use ``__init_subclass__()`` from :pep:`487`.
Requests and Responses Requests and Responses
~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~

View File

@ -1,9 +1,11 @@
import unittest
from operator import attrgetter from operator import attrgetter
from django.core.exceptions import FieldError, ValidationError from django.core.exceptions import FieldError, ValidationError
from django.db import connection, models from django.db import connection, models
from django.test import SimpleTestCase, TestCase from django.test import SimpleTestCase, TestCase
from django.test.utils import CaptureQueriesContext, isolate_apps from django.test.utils import CaptureQueriesContext, isolate_apps
from django.utils.version import PY36
from .models import ( from .models import (
Base, Chef, CommonInfo, GrandChild, GrandParent, ItalianRestaurant, Base, Chef, CommonInfo, GrandChild, GrandParent, ItalianRestaurant,
@ -156,6 +158,23 @@ class ModelInheritanceTests(TestCase):
self.assertIs(C._meta.parents[A], C._meta.get_field('a')) self.assertIs(C._meta.parents[A], C._meta.get_field('a'))
@unittest.skipUnless(PY36, 'init_subclass is new in Python 3.6')
@isolate_apps('model_inheritance')
def test_init_subclass(self):
saved_kwargs = {}
class A:
def __init_subclass__(cls, **kwargs):
super().__init_subclass__()
saved_kwargs.update(kwargs)
kwargs = {'x': 1, 'y': 2, 'z': 3}
class B(A, models.Model, **kwargs):
pass
self.assertEqual(saved_kwargs, kwargs)
class ModelInheritanceDataTests(TestCase): class ModelInheritanceDataTests(TestCase):
@classmethod @classmethod