python / expert
Snippet
Benutzerdefinierte Modell-Metaklasse für dynamische Modell-Attribut-Injektion
In der modernen Django-Architektur ermöglichen benutzerdefinierte Metaklassen, die `ModelBase` erweitern, das Eingreifen in den Python-Klassenerstellungs-Lebenszyklus, bevor Modellfelder registriert werden. Durch Überschreiben von `__new__` können Sie ORM-Feldinstanzen und dynamische Hilfsmethoden programmgesteuert in nicht-abstrakte Unterklassen injizieren.
snippet.py
python
1
2
3
4
5
6
7
8
9
10
11
12
13
from django.db import modelsfrom django.db.models.base import ModelBaseclass DynamicAuditMeta(ModelBase):def __new__(mcs, name, bases, attrs):if not attrs.get('__abstract__', False):attrs['audit_version'] = models.IntegerField(default=1)attrs['get_audit_tuple'] = lambda self: (self.pk, self.audit_version)return super().__new__(mcs, name, bases, attrs)class AuditedModel(models.Model, metaclass=DynamicAuditMeta):class Meta:abstract = True
django
Erklärung
1
from django.db.models.base import ModelBase
Importiert Djangos Kern-Metaklasse, die für die Erstellung von Modellklassen und die Feldregistrierung verantwortlich ist.
2
class DynamicAuditMeta(ModelBase):
Definiert eine benutzerdefinierte Metaklasse, die ModelBase erweitert, um das Klassenerstellungsverhalten anzupassen.
3
def __new__(mcs, name, bases, attrs):
Fängt die Klassenallokation ab und empfängt Metaklasse, Klassennamen, Basisklassen und Attribut-Wörterbuch.
4
if not attrs.get('__abstract__', False):
Prüft, ob die erstellte Klasse ein konkretes Modell und kein abstraktes Modell ist.
5
attrs['audit_version'] = models.IntegerField(default=1)
Injiziert dynamisch ein Django IntegerField in das Attribut-Wörterbuch der Klasse vor der Erstellung.
6
attrs['get_audit_tuple'] = lambda self: (self.pk, self.audit_version)
Fügt dem Modellklassen-Wörterbuch eine dynamische Hilfsmethode zur Rückgabe des Audit-Status hinzu.
7
return super().__new__(mcs, name, bases, attrs)
Delegiert die eigentliche Klassenerstellung mit den geänderten Attributen an ModelBase.__new__.