[PYTHON] Die Geschichte des Django-Modellfeldes verschwindet aus der Klasse

Überblick

――Ich habe nachgeschlagen, was mein Kollege angekündigt hatte, und habe es für mich selbst nachgeschlagen und notiert.

Klassenvariable

class Person:
    name = 'takanory'
    
Person.name # => takanory

p1 = Person()
p1.name # => takanory

assert Person.name is p1.name  # same object

Feld verschwindet aus dem Django-Modell

class Person(models.Model):
    name = models.CharField(max_length=255, default='takanory')
    age = 37

#Gewöhnliche Klassenvariablen existieren
Person.age # => 37
    
#Die Klassenvariable "Name" des Feldobjekts fehlt
Person.name 
# => AttributeError: type object 'Person' has no attribute 'name'

#Eigentlich ist "Name" "_meta.Existiert in "Feldern"
Person._meta.fields
# => (<django.db.models.fields.AutoField: id>, <django.db.models.fields.CharField: name>)

»Kein Wunder für diejenigen, die normalerweise Django verwenden

Klassen und Metaklassen

――Um diese Frage zu beantworten, müssen wir über Metaklassen sprechen. -Sie können ein Klassenobjekt mit dem Typ ** erstellen ** --Klassendefinition ist gleichbedeutend mit dem Erstellen eines Klassenobjekts mit dem Typ **

#Gewöhnliche Klassendefinition
class Person:
    name = 'takanory'

#Erstellen Sie dasselbe Klassenobjekt "Person" wie die obige Klassendefinition
Person = type('Person', tuple(), {'name': 'takanory'})

#Das Klassenobjekt ist eine Instanz vom Typ
assert isinstance(Person, type)
class Taka22(type):
    """ 
Name ist'takanory'Nur im Fall von
    nickname = 'taka22'Meta-Klasse zum Hinzufügen einer Klassenvariablen namens
    """
    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'

Folgen Sie der Quelle von Django

―― An diesem Punkt können Sie sich vorstellen, dass die Metaklasse das "Feld verschwindet" aus der Klasse ausführt. --Überprüfen Sie tatsächlich das entsprechende Teil.

Überprüfen Sie die Metaklasse der Modellklasse

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):

Wo das Feld gelöscht wird

class ModelBase(type):
    """
    Metaclass for all models.
    """
    def __new__(cls, name, bases, attrs):
        #Übergeordnete Klasse(type)von__new__Methode
        super_new = super(ModelBase, cls).__new__

        # ~Kürzung~

        # Create the class.
        module = attrs.pop('__module__')
        #Nur Modul als attr und neu übergeben_Klasse generieren
        #Zu diesem Zeitpunkt sind die Klassenvariablen verschwunden
        new_class = super_new(cls, name, bases, {'__module__': module})

# refs https://github.com/django/django/blob/master/django/db/models/base.py#L67             

Verschieben Sie Felder nach ** _meta.fields **

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) #Wert ist ein Feldobjekt
    else:
        # contribute_to_Ich habe keine Klasse
        #attr wird wie in der Klassendefinition festgelegt(Zurück)
        setattr(cls, name, value)

# refs https://github.com/django/django/blob/c339a5a6f72690cd90d5a653dc108fbb60274a20/django/db/models/base.py#L303
def contribute_to_class(self, cls, name, private_only=False, virtual_only=NOT_PROVIDED):
    # ~Kürzung

    #Über diesen Bereich erhielt ich cls(=model)von_Ich füge mich als Felder zu Meta hinzu.
    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

Zusammenfassung

--Wie verschwinden Klassenvariablen wie Felder aus Djangos Modell?

class Person(models.Model):
    name = models.CharField(max_length=255, default='takanory')
    
p1 = Person()
p1.name # => 'takanory'

#Die Instanz kann direkt auf die Wertzeichenfolge "takanory" verweisen.
#Wenn das Personenmodell instanziiert, selbst.Der "Wert" des Feldes wird dem Namen zugewiesen
#Gleichzeitig wird die Klassenvariable "Person."Name" ist "Selbst".Kann nicht mit "Name" referenziert werden
#Deshalb "Person._meta.Wird es nicht zu "Feldern" evakuiert??

Referenz

Recommended Posts

Die Geschichte des Django-Modellfeldes verschwindet aus der Klasse
Die Geschichte des Starts eines Minecraft-Servers von Discord
Die Geschichte des Exportierens eines Programms
DJango Memo: Von Anfang an (Modelleinstellung)
Die Geschichte der Verarbeitung A von Blackjack (Python)
DJango Memo: Von Anfang an (Erstellen einer Ansicht)
Die Geschichte der Anzeige von Mediendateien in Django
Die Geschichte eines Mel-Icon-Generators
Die Geschichte vom Umzug von Pipenv zur Poesie
Python scikit-learn Eine Sammlung von Tipps für Vorhersagemodelle, die häufig im Feld verwendet werden
Die Geschichte der Erstellung einer Webanwendung, die umfangreiche Lesungen mit Django aufzeichnet
Die Geschichte von Django, wie er eine Bibliothek erstellt, die vielleicht etwas nützlicher ist
Python scikit-learn Eine Sammlung von Tipps für Vorhersagemodelle, die häufig im Feld verwendet werden
Die Geschichte von sys.path.append ()
Eine Geschichte, die den Aufwand für Betrieb / Wartung reduziert
Die Wand beim Ändern des Django-Dienstes von Python 2.7 auf Python 3-Serie
Berechnen Sie das Volumen aus der zweidimensionalen Struktur einer Verbindung
Python-Implementierung der Bayes'schen linearen Regressionsklasse
Python zeigt aus der Perspektive eines C-Sprachprogrammierers
Die Geschichte eines neuronalen Netzwerks der Musikgeneration
DJango Hinweis: Von Anfang an (mit einer generischen Ansicht)
DJango Hinweis: Von Anfang an (Erstellen einer Ansicht aus einer Vorlage)
Machen Sie das Modell zu einer Zeichenfolge in der Django-HTML-Vorlage
Eine Geschichte über die Änderung des Master-Namens von BlueZ
Zip 4 Gbyte Problem ist eine Geschichte der Vergangenheit
Eine Geschichte, die die Lieferung von Nico Nama analysierte.
[Django] Geben Sie Form einen dynamischen Anfangswert aus Model
Die Geschichte des Wechsels von WoSign zu Let's Encrypt für ein kostenloses SSL-Zertifikat
Die Geschichte der Einrichtung eines VIP-Kanals im internen Chatwork
DJango Hinweis: Von Anfang an (Vereinfachung und Aufteilung von URLConf)
Die Geschichte des Baus von Zabbix 4.4
Django Model Field Customization Verschiedene
Anders als der Importtyp von Python. Bedeutung von aus A Import B.
Ich habe eine Funktion erstellt, um das Modell von DCGAN zu überprüfen
Eine Geschichte, die das Debuggen von Modellen in der Django + SQLAlchemy-Umgebung einfacher macht
Die Geschichte des Kopierens von Daten von S3 auf Googles TeamDrive
Verwenden Sie das Django-Modell vom Interpreter
Erstellen Sie ein Korrelationsdiagramm aus dem Konversationsverlauf von Twitter
Immerhin die Geschichte der Rückkehr von Linux zu Windows
Analysieren Sie das Themenmodell, mit GensimPy3 Romanautor zu werden
Die Geschichte des Erstellens einer Datenbank mithilfe der Google Analytics-API
Die Geschichte, wie man mit discord.py einen Fragenkasten-Bot erstellt
Eine Geschichte über die Vorhersage von Präfekturen aus Städtenamen mit Jubatus
[Django] Was tun, wenn das zu erstellende Modell viele Felder enthält?
Erstellen Sie eine Instanz einer vordefinierten Klasse aus einer Zeichenfolge in Python
Eine Geschichte, die mit der Installation der maschinellen Lernbibliothek JAX zusammenhängt
Eine Formel, die einfach das Alter ab dem Geburtsdatum berechnet
Die Geschichte, einen Standardtreiber für db mit Python zu erstellen.
[Python] Ruft das Aktualisierungsdatum eines Nachrichtenartikels aus HTML ab
[Django] Korrigieren Sie die Pluralform des Modellnamens auf dem Verwaltungsbildschirm
Die Geschichte der Erstellung einer Website, auf der die Veröffentlichungsdaten von Büchern aufgeführt sind
Bewerten Sie die Leistung eines einfachen Regressionsmodells mithilfe der LeaveOneOut-Schnittstellenvalidierung
Bewerten Sie die Genauigkeit des Lernmodells durch einen Kreuztest von scikit learn
Die Geschichte, ein Modul zu erstellen, das E-Mails mit Python überspringt
Beste 3 aus den Eindrücken des Lesens des neuen Shell-Programmierlehrbuchs
Die Geschichte, dass "calendar.day_abbr" auf dem Admin-Bildschirm von django nicht aktualisiert werden konnte
Die Geschichte von Python und die Geschichte von NaN