I understand that when a class inherits from an Abstract Django Model, it will not inherit the meta attribute abstract = True
, which makes sense.
However in the below example nothing has inherited from it, but yet it's Meta.abstract
is False
even though its defined to be True
:
from django.db import models
from django.db.models.base import ModelBase
class MyMeta(ModelBase):
def __new__(cls, name, bases, attrs, **kwargs):
"""Check that all implemented (not abstract) classes have a foo attribute"""
Class = super().__new__(cls, name, bases, attrs, **kwargs)
if not Class.Meta.abstract:
print(Class)
print('Class.Meta.ordering:', Class.Meta.ordering) # Sanity check
print('Class.Meta.abstract:', Class.Meta.abstract)
if not hasattr(Class, 'foo'):
raise NotImplementedError('Please add a foo attribute')
return Class
class MyAbstractModel(models.Model, metaclass=MyMeta):
name = models.CharField(max_length=250)
class Meta:
abstract = True
ordering = ('-name',)
Prints:
<class 'myapp.models.base.MyAbstractModel'>
Class.Meta.ordering: -name
Class.Meta.abstract: False
Add raises (even though it should not raise because it is an abstract class):
NotImplementedError: Please add a foo attribute
CodePudding user response:
You are accessing the wrong attribute, namely Class.Meta
. Since this attribute will be inherited by any child classes Django actually modifies [GitHub] it for abstract models:
if abstract: # Abstract base models can't be instantiated and don't appear in # the list of models for an app. We do the final setup for them a # little differently from normal models. attr_meta.abstract = False new_class.Meta = attr_meta return new_class
The attribute Django actually uses behind the scenes (All of the attributes are properly copied over to it) is _meta
. Hence if you write the following you'll get the expected result:
if not Class._meta.abstract:
...
CodePudding user response:
Abstract is False because children classes don't become abstract classes themselves. You need to explicitly set it True. There is info about that in the docs. https://docs.djangoproject.com/en/4.1/topics/db/models/