«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