Cum Django foloseste descriptorii de date si metaclasele pentru modelarea datelor

Inainte de a continua sa cititi: acesta este un articol Python de nivel intermediar si superior. Pentru a va angaja pe deplin cu conceptele din acest articol, va trebui sa va familiarizati cu conceptele de baza Django si sa cunoasteti solid modelul de programare orientat obiect al Python.

Django este unul dintre cele mai folosite framework-uri web Python open-source din cadrul comunitatii Python, multe dintre instrumentele sale incorporate presupunand ca dezvoltatorii vor lucra intr-un model de proiectare Model-View-Template (MVT) .

Majoritatea dezvoltatorilor nu au niciodata sansa de a vedea functionarea interioara a Django. Ne vom concentra atentia in mod specific asupra abordarii modelului de date declarativ bazat pe clasa a lui Django si a modului in care Django ofera o interfata mai curata pentru dezvoltatorii care folosesc metaclasele.

Vom incepe prin a construi un exemplu simplu de aplicatie numit excluderi . Daca dorim sa reprezentam un student , am incapsula atat comportamentul schematic ( care sunt atributele, tipurile de date si relatiile acestui student ? ), Cat si comportamentul functional ( cum ar arata studentul nostru ipotetic_status_towards_graduation () ? ) Intr- o definitie a clasei din cadrul nostru pachetul Python al aplicatiei, de obicei intr-un fisier numit models. alpha france porno py :

Un simplu student modelul cu 4 campuri – un id , primul nume , ultimul nume , si un atribut obisnuit numit id_field .

Aceasta este mai mult sau mai putin din perspectiva dezvoltatorului. De acolo, Django gestioneaza tot codul de plumbare pentru a va sincroniza noul model de date cu un tabel de baze de date backend prin intermediul gestionarii . py makemigrations excluderi , cu validarea si persistente legate de cazuri noi de student , impunerea relatiilor cheie externa si constrangeri, etc. Aceasta este in mod traditional domeniul contractului de delimitare intre Django dezvoltator web si o sursa de Django contributor- declarati clase ca modelul dvs. sa fie conforme cu un model specific , iar Django ia aceasta clasa statica si o transforma in ceva capabil de interactiune in timpul rularii – ceva modular care poate fi conectat la un cadru web.

Ce face Django pentru tine?

Sa trecem peste acea limita a domeniului si sa analizam o lista cu unele dintre functionalitatile pe care un dezvoltator Django se asteapta „gratuit” ori de cate ori defineste o clasa de model de date:

  • Asociati in mod explicit (adica „inregistrati”) acest student nou definit cu aplicatia corecta ( excluderi )
  • Determinati daca clasa modelului definit este o clasa abstracta sau concreta – aceasta are in mod evident implicatii semnificative, deoarece nu vrem ca Django sa creeze un lant de tabele de clase abstracte in baza de date backend (daca HighSchoolStudent subclaseaza o clasa de model Student abstract , care este in sine o subclasa unei clase de model Persoane abstracte , dorim sa fie creata doar o tabela HighSchoolStudent . casting porno français
  • Gestionati in mod inteligent autorizarea pentru modele la nivel granular ( cine poate adauga, modifica, sterge sau vizualiza acest model? )
  • Conectati relatiile de traversare implicite (si explicite) intre diferite obiecte Model pentru a permite accesul programatic in directii inainte / inapoi. Django se refera la faptul ca acestea sunt proprietati inainte si inversa si creeaza o clasa imbricata numita Optiuni care detine aceste informatii. De exemplu, daca o instanta Student are un atribut numit school_id , care face referire la o instanta School , este destul de evident ca puteti accesa scoala prin student.school_id . Cu toate acestea, exista unele lucrari implicate in pre-calcularea listei instantelor studentesti care se asociaza cu un anumit school_id.
  • Puneti in aplicare o separare a preocuparilor oferind o granita de domeniu logica si un container pentru partitionarea campurilor de date ale modelului cu informatii despre metadate. De exemplu, implementarea pentru suprascrierea numelui de tabel backend atribuit unui model Django ar trebui sa existe in afara de cunoasterea anumitor atribute de camp care definesc un model Student . porno perfecte

Acesta este doar inceputul. La runtime, Django citeste definitiile clasei modelului dvs. de date si pregateste clase noi, specializate, pentru a gestiona functionalitatea de care aveti nevoie intr-un ORM ( mapor relational de obiecte ). Deci, ce se intampla in culise? Mai intai vom face un pas inapoi si vom analiza o componenta fundamentala de nivel scazut a masinilor Python: metaclasele .

Prezentare generala a metaclaselor

Metaclasele sunt adesea un subiect controversat in cadrul comunitatii Python, cu o critica comuna fiind ca este dificil de gasit un caz de utilizare concret pentru metaclasele care nu pot fi implementate la fel de eficient cu mecanici de programare Python mai „traditionali” orientati pe obiecte. Meritele metaclaselor ar putea fi o carte completa in ea insasi, asa ca ma voi concentra pe oferirea unei imagini succinte asupra modului in care metaclasele creeaza clasele Python pe care le cunoastem si le iubim si le instantiem.

Vom pregati un set de clase simulate ( Student , ModelField si Model ) si metaclasa ( ModelBase ) care au acelasi nume ca modelele de baza ale lui Django si vom trece printr-un exemplu simplu de ceea ce se intampla atunci cand metaclasele sunt utilizate pentru a personaliza crearea clasei. porno ub Retineti ca am ales in mod deliberat sa folosesc aceleasi nume pentru aceste clase si metaclase ca echivalentele lor Django, in ciuda faptului ca nu am implementat niciuna dintre functionalitatile lor, pur si simplu, astfel incat sa putem separa in mod intentionat complexitatea metaclaselor de complexitatea celorlalte masini interne de dezvoltare web Django.

In fragmentele de mai jos, Studentul nostru este mai mult sau mai putin doar o clasa obisnuita Python a carei declaratie si instantare declanseaza o multime de instructiuni de imprimare (…) , dar in cadrul Django, definind o clasa personalizata care mosteneste de la pachetele Model o intreaga gama de functionalitati si analiza atributelor pentru a pregati clasa pentru utilizare intr-un cadru web MVT (model-vizualizare-sablon):

Model, ModelField si declaratii de clasa Student . Aici, Student este mai mult sau mai putin doar o clasa Python obisnuita a carei declaratie si instantare declanseaza o multime de instructiuni de tiparire (.. ecoliere porno .) , dar in cadrul Django, definind o clasa personalizata care mosteneste de la django.db.models.base. Modelul injecteaza o intreaga gama de functionalitati si analiza atributelor pentru a pregati clasa pentru utilizare intr-un cadru web MVT.

ModelField este pur si simplu un substituent – il vom folosi pentru a infasura orice atribute intregi pe care le gasim in modelul de clasa original si pentru a-i oferi unele functionalitati complicate, cum ar fi save_value_to_persistent_store sau compute_some_complex_relationhip menite sa reflecte tipurile de operatii pe care instantele modelului de date trebuie sa le efectueze in un cadru web pentru a-si sincroniza timpul de executie in modelul de memorie cu baza de date backend si pentru a impune integritatea referentiala programatic. porno 69

In continuare, vom defini o metaclasa practic inutila, dar valoroasa pentru depanare, numita ModelBase :

Declaratia de metaclasa ModelBase. Observati ca am adaugat a_variable_from_metaclass, setati valoarea spatiului de nume some_variable la 5 in timpul invocarii sale __new__ si apoi in timpul initializarii clasei, incercati sa resetati valoarea spatiului de nume some_variable la 4 si setati o noua variabila numita variable_added_during_init la „boom”.

Putem apoi sa parcurgem ceea ce se intampla sub capota atunci cand este creata o instanta a Studentului si sunt accesate anumite atribute (cum ar fi some_variable , variable_added_during_init si a_variable_from_metaclass ):

student = Student ()



print (student.some_variable)



print (student.age)



print (student.variable_added_during_init)

Iesirea pe care o primim arata ordinea invocarii diferitelor metode ModelBase :

Poate cel mai important aici este faptul ca sesizarea declarat anterior intreg de atribute – ambele sunt definite in mod explicit in Student (cum ar fi varsta ), precum si cele atasate in __new__ apelul de ModelBase (cum ar fi some_variable ) – sfarsesc ca instante distincte de ModelField .

Asigurati – va ca va aflati clar la ce nivel de abstractizare functioneaza fiecare metoda cu – dvs. les plus belles actrices porno traditional run-of-the-mill __init__ ia intr – un obiect construit anterior instanta, de obicei , numit de sine ca prim argument, ci o metaclass’ __init__ ia intr – un obiect de clasa cls . De exemplu, daca ati rulat student.a_variable_from_metaclass pentru a incerca sa accesati atributul variable_from_metaclass = 4 definit in ModelBase , veti primi

AttributeError: obiectul „Student” nu are atributul „a_variable_from_metaclass”

Cu toate acestea, daca rulati Student.a_variable_from_metaclass , veti primi valoarea asteptata de 3 . A_variable_from_metaclass se gaseste in cadrul clasei __dict__ , nu instanta de __dict__ .

Un exemplu perfect de atribut la nivel de metaclasa este ModelBase._instances , care este declarat ca un dictionar care va tine evidenta tuturor instantelor create pentru o anumita clasa construita din ModelBase . liza monet porno Retineti ca metoda __call__ ia clasa ca primul sau argument cls , deci ori de cate ori cream o noua instanta in __call__ , putem adauga o referinta la aceasta noua instanta in dictionarul nostru _instances :

# stackoverflow.com / questions / 6760685 / creating-a-singleton-in-python



if cls not in cls._instances:



cls._instances [cls] = super () .__ call __ (* args, ** kwargs)



return cls._instances [cls]

Acesta este un mod eficient de a aplica un model de proiectare Singleton , de exemplu, pentru a preveni instantierea falsa a obiectelor scumpe de memorie (cum ar fi conexiunile la baza de date):

student = Student ()



student2 = Student ()



student3 = Student ()



print (student) # <__ main __. Student object at 0x10cecb6d0>



print (student2) # <__ main __. porno party Student object at 0x10cecb6d0>



print (student3) # <__ main __. Student obiect la 0x10cecb6d0>

Fluxul de lucru la nivel inalt pentru crearea clasei. Functiile colorate apeleaza __prepare__ , __new__ si __init__ sunt metode legate de metaclasa ModelBase. Obiectul suprem creat este Student , o clasa pentru copii a clasei Model Django .

De fapt, putem crea noi clase dinamic, pur si simplu trecand intr-un sir de nume de clasa nou, un tuplu de clase de baza si un spatiu de nume de clasa. Sa presupunem ca dorim sa cream un mesaj specializat de exceptie care sa fie ridicat, astfel incat sa putem identifica rapid la rulare care dintre sutele de modele de date distincte este nefericit, in loc sa treci prin cuiburi de urme de stiva:

StudentException = ModelBase („StudentException”, (Exception,), {})



print (StudentException) <clasa ‘__main __. StudentException’>

Atunci cand cream o exceptie StudentException , putem genera un indiciu de traceback semnificativ mai util pentru a incepe procesul de depanare cu:

Traceback (ultimul apel cel mai recent):



fisierul „/Users/yuchen/PycharmProjects/python_advanced/metaclasses. porno alpha py”, linia 67, in <module>



ridica StudentException (eroare)



__principal __. StudentException: Ceva nu era in regula cu atributul acestui student

Chiar si in exemplul nostru trivial, am vazut ca aceste trei metode – __prepare__ , __new__ si __init__ pot fi folosite pentru a ingriji o noua clasa de utilizare inainte de a o face disponibila pentru instantiere:

  • Aderati dinamic la noile instante si atribute de clasa, cum ar fi some_variable si a_variable_from_metaclass, la noi clase si instante create din ModelBase
  • Analizati atributele in Student si convertiti-le intr-o alta forma, poate un tip de obiect mai robust (in cazul nostru, de la un int la ModelField ) cu metode suplimentare de conectare la baze de date sau metadate referentiale cu alte instante ale Studentului .
  • Aplica o anumita politica de instantiere a obiectelor (model de proiectare Singleton) pentru toate clasele create de dezvoltatori care folosesc ModelBase ca eventuala metaclasa in ierarhia lor de clase.

Sa legam acum toate aceste discutii conceptuale cu Django.

Metaclasa ModelBase a lui Django

Modelele de date Django (cele pe care le definim ca dezvoltatori) sunt subclasele Model , care au ca metaclasa ModelBase . Va puteti gandi la metaclasa ModelBase ca la o fabrica de clase de modele de date, una care fabrica clase pregatite, ca Student, cu suficiente meta-date si functionalitate pentru a putea fi conectat direct la restul cadrului Django. La un nivel ridicat, relatia dintre Student , Model si ModelBase poate fi surprinsa in urmatoarea diagrama:

Observati ca obiectul subclaselor Model, obiectul arhetipal din clasa Python, in timp ce tipul subclaselor ModelBase, care este metaclasa de baza. porno gros plan

ModelBase metaclass va construi nostru Student model de date de clasa printr – o secventa de apeluri:

__a pregati__

Metoda clasei __prepare __ (metacluri, nume, baze, ** kwargs) include un nume de sir al clasei de creat si un tuplu de clase de baza numit baze si returneaza o mapare a spatiului de nume al dictionarului Python. Metaclasa ModelBase a lui Django nu suprascrie __prepare__ , asa ca am scris propria mea suprascriere pentru urmarire si depanare, care imprima pur si simplu cateva argumente si apoi delega apelul __prepare__ la tip (adica super () ).

Retineti ca in mod traditional, o metoda decorata @classmethod ar trece in instanta cls (de exemplu, clasa in sine) ca primul argument. Aici, primul argument este metaclasa ModelBase .

Daca importam fisierul nostru models.py care contine definitia clasei Student , vom vedea urmatoarea iesire:

Observati ca prima executie a __prepare__ este utilizata pentru a crea clasa Model – abia dupa ce Modelul a fost definit, incepem crearea Studentului si indicati ca subclaseaza clasa Model care tocmai a fost creata anterior.

Aveti grija sa nu confundati discutia noastra despre __prepare__ , care este o componenta a masinii de nivel scazut a Python pentru crearea spatiului de nume al clasei, cu metoda statica ModelBase. plan a 3 porno _prepare () a lui Django , care se numeste in metoda de creare a clasei __new__ .

__new__ Partea I: Verificari inainte de creare

Odata ce noul spatiu de nume al clasei a fost alocat si pregatit, are loc lucrarea reala de pregatire a unui model de date definit de utilizator. ModelBase suprascrie intr-adevar __new__ , iar marea majoritate a logicii din fabrica a claselor modelelor de date are loc intr-adevar in cadrul acestei metode. De la ModelBase al lui Django . Implementarea __new__ este destul de lunga, haideti sa impartim apelul in sectiuni mai mici si sa parcurgem fiecare in parte pentru a intelege ce se intampla in culise atunci cand declaram o noua clasa de model de date:

Prima portiune a apelului __new__ efectueaza trei verificari principale:

  • Existenta claselor parinte care sunt, de asemenea, create din sablonul de metaclasa ModelBase : de exemplu, cand Modelul este creat pentru prima data, clasa sa de baza parinte este implicit obiect , care are o metaclasa de tip .



    • porno adulte
    • overwatch porno
    • télé réalité porno
    • papa porno
    • video porno lingerie
    • porno horreur
    • lupo porno
    • brigitte lahaie film porno
    • porno?trackid=sp-006
    • porno katsumi
    • film erotique porno
    • sport porno
    • vieux film porno
    • blanche neige porno
    • video porno medecin
    • sos porno
    • victoria abril porno
    • viole porno
    • porno harem
    • totally spies porno





    Deoarece lista de parinti va fi goala pentru Model , creatia obisnuita a clasei dvs. continua printr-un apel catre super_new (cls, nume, baze, attrs) . koh lanta porno Pentru student , cu toate acestea, baza sa este modelul clasa, care este intr – adevar o instanta a ModelBase . Prin urmare, executia continua dupa linia 10 din fragmentul de mai sus.

  • Populatia de contributable_attrs , care este un dictionar de nume de atribute sir si de obicei valorile lor atribuite instantei de camp . Pentru Student , acesta este prenumele , prenumele si studentul . Orice instanta a campului sau a unei clase de copii Django, cum ar fi CharField, are o metoda contribution_to_class () care asociaza fiecare instanta de camp cu clasa model in care este declarata. Functia Student .__ str__ , de exemplu, nu este etichetata. perfect girl porno Retineti ca aici este modelul lui Djangoincepe sa se diferentieze de o clasa traditionala – inainte ca orice instanta a unei subclase de model sa fie instantaniata vreodata, Django stie care sunt atributele „specifice Django” si care sunt atributele traditionale Python. Dupa aceasta verificare, dictionarul contributable_attrs va fi completat cu toate numele campurilor Student si tipurile de campuri corespunzatoare :

{‘first_name’: <django.db.models.fields.CharField>,



‘last_name’: <django.db. aphrodite porno models.fields.CharField>,



‘student_id’: <django.db.models.fields.CharField>}

Metoda add_to_class a ModelBase efectueaza greutatea ridicata in ceea ce priveste stabilirea unde ar trebui sa mearga atributele noi – acele atribute care sunt determinate sa nu fie contributive_attrs sunt pur si simplu adaugate la clasa „ __dict__ printr-un apel setattr (. film porno maroc .. ):

def add_to_class (cls, nume , valoare ): # cls este noua clasa creata in __new __ (…)



daca _has_contribute_to_class ( valoare ):



valoare .contribute_to_class (cls, nume )



altceva :



setattr (cls, nume , valoare )

  • Existenta unei clase Meta imbricate – aceasta este interfata principala a clasei declarative pentru atasarea atributelor de metadate partajate, cum ar fi abstract , sau ordonare sau verbose_name_plural . porno ado In cazul nostru, deoarece nu am definit o clasa Meta interioara , attr_meta este setata la None . Daca, de exemplu, as fi definit clasa mea de student mai jos:

Clasa Meta imbricata serveste scopului unui container de informatii meta-date – informatiile despre Student sunt un atribut de clasa de nivel superior; informatii despre modul de utilizare a Studentului in contextul Django sunt populate in cadrul clasei Meta .

In acest caz, attr_meta devine o clasa obisnuita Python numita Meta .

__new__ Partea II: Crearea clasei noi si atasarea atributelor

Toate atributele „obisnuite” ale clasei studentesti ( id_field , __str__ , __qualname__ , __module__ ) sunt stocate intr-un dictionar nou numit new_attrs . Acestea sunt apoi transmise in apelul super_new (… porno a la ferme ) pentru a crea new_class , care este noua noastra cursa pregatita Student (fara niciun atribut specific Django). Daca noi_attrs . __dict__ imediat dupa ce revine din acest apel, vedem

__New__ apela apoi verifica daca exista o meta clasa care are un atribut configurat numit abstract . Aceasta valoare implicita este False, deoarece Django are nevoie de un mecanism pentru a se asigura ca copiii din clasele de modele abstracte nu devin ei insisi abstracte.

Django verifica apoi daca modelul Student (daca nu este abstract, ceea ce nu este) este fie inregistrat in mod explicit printr-o eticheta app_l, fie ca numele aplicatiei ( excluderi ) este listat in lista INSTALLED_APPS din setarile Django . fisier py . Campul app_label este obligatoriu pentru modelele definite in afara domeniului de aplicare al aplicatiilor INSTALLED_APPS , dar este, de asemenea, prepopulat de metaclasa, astfel incat Django sa poata efectua cautari pentru a accesa configuratii specifice aplicatiei in timpul rularii. pokemon porno

De asemenea, in acest moment Django adauga un container Optiuni clasei nou create ca un atribut numit _meta:

new_class.add_to_class (‘_ meta’, Optiuni (meta, app_label))

Atributul _meta gazduieste o lista enorma de meta-date configurabile, inclusiv

  • afiseaza setari precum verbose_name si verbose_name_plural
  • permisiuni si permisiuni implicite
  • definitii de tip de clasa de model (concret, proxy, abstract etc.)
  • instructiuni de ordonare si sortare cu ordonare si ordine_cu_respect_to

Intr-adevar, daca nu sunteti sigur unde este probabil gazduita o bucata de meta-date configurabile legate de Student, este probabil ca instanta Optiuni sa fie atribuita atributului _meta.

Apoi, Django pregateste doua subclase speciale de exceptieMultipleObjectsReturned ridicat ori de cate ori o interogare a gasit mai multe inregistrari cand se astepta doar 1) si DoesNotExist (s-au gasit 0 inregistrari cand se astepta cel putin 1) care sunt imbricate in mod specific in clasa Student :

Retineti ca subclass_exception este o functie din fabrica care utilizeaza metaclasa de tip pentru a crea noi clase care sunt complet calificate in clasa originala:

Pentru Student , aceasta inseamna ca primim „gratuit” Studentul . Nu exista si student . MultipleObjects Exceptii returnate pentru a lucra in timpul rularii pentru a identifica rapid sursa erorilor comune de interogare a bazei de date.

Clase de rezumat si proxy in Django

Django face o utilizare semnificativa a mix-urilor Python pentru a combina elemente modulare de functionalitate. feet porno De exemplu, puteti crea un PermissionsMixin pentru a gestiona interactivitatea modelului dvs. de date:

Acest lucru ar putea fi apoi integrat intr-un alt model de date pentru a adauga functionalitatea de autorizare a anumitor actiuni sau domenii de vizibilitate – de exemplu declararea clasei Student (PermissionsMixin): ….

Cand o clasa de model de date este declarata ca abstracta in Django, numai clasele derivate din aceasta clasa abstracta ar trebui sa aiba tabele de baze de date create.

In mod similar, Django foloseste un concept numit modele proxy pentru a suprascrie functionalitatea existenta intr-un alt model fara a crea o noua tabela de baze de date backend. De exemplu, as putea adauga o anumita logica personalizata la perform_student_specific_action (…) care va interoga in continuare folosind modelul original Student pentru un anumit subgrup de studenti:

Cu clase abstracte, mixine si modele proxy, conceptul Django de clase abstracte informeaza in primul rand modul in care aceste clase interactioneaza cu baza de date backend si modul in care campurile sunt mostenite din clasele de baza.

Prin urmare, inainte de a elibera o noua clasa de date creata pentru instantierea, cadrul Django trebuie sa efectueze o varietate de verificari ale calitatii modelului:

  • Asigurati-va ca clasa derivata, concreta, nu doar mosteneste campurile declarate si atributele meta ale clasei sale de baza abstracte, ci realizeaza aceasta mostenire in ordinea corecta de rezolutie a metodei. Aceasta sarcina pare banala pentru clasele Python obisnuite (deoarece masinile incorporate Python gestioneaza toate acestea pentru dvs.), dar surprinzator de complexa si plina de cazuri marginale folosind modele de date Django (de exemplu, trebuie sa ne asiguram ca numai campurile care nu sunt suprapuse din clasele de baza abstracte sunt mostenite si ca mostenim o copie profunda distincta a campului, in loc de o referinta a indicatorului la campul original:

Logica pentru adaugarea campurilor, gasita in apelul __new__ al ModelBase.

  • Asigurati-va ca clasele proxy respecta structura corecta de mostenire specifica domeniului Django (una si nu mai mult de o clasa de baza non-abstracta, fara clase abstracte care contin campuri de model etc.):

Logica pentru validarea structurii de mostenire proxy, gasita in apelul __new__ al ModelBase.

  • Asigurati-va ca mostenirea campului privat nu duce la ciocniri de nume:

Intr-adevar, toate acestea au loc in cadrul apelului la metoda __new__ . Acestea sunt doar cateva exemple de logica de validare care se executa inainte ca orice modele de date personalizate sa fie instantiate vreodata si putem vedea cat de mult se bazeaza Django pe logica din __new __ (…) a ModelBase pentru a se asigura ca toate clasele de model de date livrat intr-o aplicatie Django este echipat cu instrumentele si starea interna pentru a reusi in timpul rularii.

In acest moment, ar fi corect sa ne intrebam de ce sa trecem prin complexitatea suplimentara si nivelul de indirectie pentru a lucra cu metaclasele in loc sa folosim pur si simplu initializatorul de instanta __init __ (auto, …) pentru a pregati o instanta? Raspunsul, desigur, este ca cu siguranta puteti implementa – desi cu atentie si intr-o maniera predispusa la erori – aceeasi functionalitate. Ca si in cazul oricarei alegeri de design, rezultatele finale reprezinta un set de compromisuri: metaclasele lui Django ridica temporar barierele de intrare pentru cineva care cauta sa contribuie la cadrul in sine , dar in mod corespunzator aplatizeaza curba de invatare pentru dezvoltatorul web casual care cauta pur si simplu un set de instrumente pentru modelarea domeniului ei de afaceri.

De ce metaclasele faciliteaza viata dezvoltatorului Django? Voi expune doua motive principale:

  • Modularitate impusa prin design bazat pe domenii : functionalitatea incorporata intr-o platforma web moderna este extrem de complexa si una la care nicio persoana nu ar putea pretinde ca este experta. Fara o modalitate de a reduce spatiul contextual, chiar si persoanele care sunt intim familiare cu functionarea interioara a lui Django ajung sa plateasca un context fiscal semnificativ care sa comute intre modelarea datelor, autentificarea, relatiile entitatii backend, proiectarea algoritmilor, validarea formularelor etc. Prin urmare, angajarea metaclasele permit contextului delimitat al dezvoltatorului web Django sa stea la nivelul modelului clasei de date (in cazul nostru, Student ), unde se poate concentra pe modelarea interactivitatii dintre un student si o scoala, in loc de detalii de nivel inferior, cum ar fi proiectarea algoritmilor cazan-placa pentru a cauta in mod corespunzator campuri de-a lungul ierarhiei clasei parinte.
  • Calitate imbunatatita a datelor prin atenuarea efectului lantului de lanturi de aprovizionare si a fluxurilor de lucru din fabrica. Prinderea erorilor si a logicii incorecte in timpul definirii si crearii clasei inseamna ca dezvoltatorii suporta timp suplimentar de depanare si dezvoltare, da; a lasa aceste erori sa curga la instantierea modelului si timpii de executie a productiei inseamna a suporta costul unei experiente scazute a utilizatorului si poate chiar mai rau – comportament imprevizibil al modelului de date.

Intr-adevar, actul de definire a unei clase Student este un proces de fabricatie in sine, cu diferite „etape” ale procesului adaugand treptat caracteristici modulare si efectuand validari specifice contextului. Mutarea logicii pentru validari si adaugarea atributelor la apelul __new__ permite crearea clasei sa „esueze rapid si sa esueze puternic”, reducand probabilitatea unui model de date „zombie”: o tabela de baze de date orfane provenita dintr-un model semi-coerent cu mix de functionalitate si valori de camp rupte, care inca se ascund in timpul rularii.

Din aceasta perspectiva, nu numai ca este cea mai buna practica de a detecta erorile cat mai devreme posibil, ci de a reduce cantitatea de variabilitate in amonte intr-un proces de fabricatie – standardizarea fluxului de lucru de creare a clasei pentru toate obiectele modelului de date Django prin impingerea cat mai multa logica a cazanului in amonte de metaclasa ModelBase inseamna ca variabilitatea implementarii poate fi gasita la nivelul corect de abstractizare.

Cu alte cuvinte, nu ar trebui sa existe o multitudine de modalitati de a mosteni campuri din clasele de baza sau de a implementa incarcarea lenesa dintr-un tabel de baze de date – acestea sunt probleme rezolvate care beneficiaza de un proces standardizat pentru a atenua problemele de runtime din aval. In schimb, metaclasele Django ofera o modalitate de a se asigura ca toti dezvoltatorii – indiferent de expertiza tehnica de nivel scazut – incep de la aceeasi linie de baza si isi pot orienta atentia spre definirea entitatilor si modelarea logicii de afaceri si a relatiilor din viata reala din codul lor.