«J'ai regardé ce que mon collègue avait annoncé, je l'ai recherché moi-même et en ai pris note.
class Person:
name = 'takanory'
Person.name # => takanory
p1 = Person()
p1.name # => takanory
assert Person.name is p1.name # same object
class Person(models.Model):
name = models.CharField(max_length=255, default='takanory')
age = 37
#Des variables de classe ordinaires existent
Person.age # => 37
#La variable de classe "nom" de l'objet champ est manquante
Person.name
# => AttributeError: type object 'Person' has no attribute 'name'
#En fait, "nom" est "_meta.Existe dans "champs"
Person._meta.fields
# => (<django.db.models.fields.AutoField: id>, <django.db.models.fields.CharField: name>)
――Pas étonnant pour ceux qui utilisent habituellement Django
«Pour répondre à cette question, nous devons parler de métaclasses. -Vous pouvez créer un objet de classe avec ** type **
#Définition de classe ordinaire
class Person:
name = 'takanory'
#Créez le même objet de classe "Personne" que la définition de classe ci-dessus
Person = type('Person', tuple(), {'name': 'takanory'})
#L'objet de classe est une instance de type
assert isinstance(Person, type)
class Taka22(type):
"""
nom est'takanory'Uniquement dans le cas de
nickname = 'taka22'Meta class pour ajouter une variable de classe appelée
"""
def __new__(cls, name, bases, attrs):
if attrs.get('name') == 'takanory':
attrs['nickname'] = 'taka22'
return super().__new__(cls, name, bases, attrs)
class Person(metaclass=Taka22):
name = 'takanory'
Person.nickname # => 'taka22'
――À ce stade, vous pouvez imaginer que la métaclasse fait le "champ disparaît" de la classe.
class Model(six.with_metaclass(ModelBase)):
_deferred = False
def __init__(self, *args, **kwargs):
# refs https://github.com/django/django/blob/master/django/db/models/base.py#L355
# python3
class Hoge(metaclass=NewMeta):
# python2
class Hoge(object):
__metaclass__ = NewMeta
# python3 and python2
class Hoge(six.with_metaclass(NewMeta):
--Dans la métaclasse ** ModelBase , attrs (contenant des variables de classe) n'est pas passé à new (super_new) dans la classe parente ( type **) -Seul ** __module __ ** est passé comme attrs. À ce stade, toutes les variables de classe telles que les objets de champ ont disparu de la définition de classe.
class ModelBase(type):
"""
Metaclass for all models.
"""
def __new__(cls, name, bases, attrs):
#Classe parent(type)de__new__Méthode
super_new = super(ModelBase, cls).__new__
# ~réduction~
# Create the class.
module = attrs.pop('__module__')
#passer uniquement le module comme attr et nouveau_Classe de génération
#À ce stade, les variables de classe ont disparu
new_class = super_new(cls, name, bases, {'__module__': module})
# refs https://github.com/django/django/blob/master/django/db/models/base.py#L67
def add_to_class(cls, name, value):
# We should call the contribute_to_class method only if it's bound
if not inspect.isclass(value) and hasattr(value, 'contribute_to_class'):
value.contribute_to_class(cls, name) #value est un objet de champ
else:
# contribute_to_Je n'ai pas de cours
#attr est défini comme dans la définition de classe(Être retourné)
setattr(cls, name, value)
# refs https://github.com/django/django/blob/c339a5a6f72690cd90d5a653dc108fbb60274a20/django/db/models/base.py#L303
-Réglé sur ** Model._meta.fields ** dans ** contrib_to_class ** de ** Field **
def contribute_to_class(self, cls, name, private_only=False, virtual_only=NOT_PROVIDED):
# ~réduction
#A propos de cette zone, j'ai reçu des cls(=model)de_Je m’ajoute en tant que champs à la méta.
self.model = cls
if private_only:
cls._meta.add_field(self, private=True)
else:
cls._meta.add_field(self)
if self.choices:
setattr(cls, 'get_%s_display' % self.name,
curry(cls._get_FIELD_display, field=self))
# refs https://github.com/django/django/blob/master/django/db/models/fields/__init__.py#L678
class Person(models.Model):
name = models.CharField(max_length=255, default='takanory')
p1 = Person()
p1.name # => 'takanory'
#L'instance peut faire directement référence à la chaîne de valeur "takanory"
#Lorsque le modèle Person s'instancie, self.La "valeur" du champ est affectée au nom
#Dans le même temps, la variable de classe "Personne."nom" est "soi".Ne peut pas être référencé par "nom"
#Par conséquent, "Personne._meta.N'est-il pas évacué vers des "champs"??
Recommended Posts