Kako napisati učinkovite prikaze, modele i upite u Djangu

Sviđa mi se Django. To je dobro promišljen i intuitivan okvir s imenom koje mogu izgovoriti naglas. Pomoću njega možete brzo pokrenuti projekt veličine vikenda, a možete ga koristiti i za pokretanje cjelovitih proizvodnih aplikacija.

Radio sam obje ove stvari i tijekom godina otkrio sam kako koristiti neke od Djangovih značajki za maksimalnu učinkovitost. Ovi su:

  • Prikazi temeljeni na klasi u odnosu na funkcije
  • Django modeli
  • Dohvaćanje objekata s upitima

Pogledajmo kako vam ovi alati omogućuju stvaranje učinkovite Django aplikacije koju je ugodno graditi i održavati.

Prikazi temeljeni na klasi u odnosu na funkcije

Sjetite se da je Django sav Python ispod haube. Što se tiče prikaza, imate dva izbora: funkcije prikaza (ponekad se nazivaju i "pogledi zasnovani na funkcijama") ili pogledi na temelju klase.

Prije godina, kada sam prvi put izgradio ApplyByAPI, on se u početku sastojao u potpunosti od prikaza temeljenih na funkcijama. Oni nude detaljnu kontrolu i dobri su za primjenu složene logike. Baš kao i u Python funkciji, i vi imate potpunu kontrolu (u dobru ili u zlu) nad onim što radi prikaz.

Ali uz veliku kontrolu dolazi i velika odgovornost, a pogledi zasnovani na funkcijama mogu biti pomalo zamorni za upotrebu. Odgovorni ste za pisanje svih potrebnih metoda za rad pogleda - to je ono što vam omogućuje potpuno prilagođavanje vaše aplikacije.

U slučaju ApplyByAPI, bilo je rijetka mjesta na kojima je ta razina prilagođene funkcionalnosti zaista bila potrebna. Svugdje drugdje, stavovi utemeljeni na funkcijama počeli su mi otežavati život. Pisanje onoga što je u osnovi prilagođeni prikaz za pokretanje tekućih operacija, poput prikazivanja podataka na stranici s popisom, postalo je zamorno, ponavljalo se i podložno pogreškama.

S prikazima koji se temelje na funkcijama, trebat ćete otkriti koje Django metode primijeniti kako bi obrađivali zahtjeve i prosljeđivali podatke pogledima. Jedinično testiranje može potrajati nekoliko poslova. Ukratko, zrnasta kontrola koju nude pogledi zasnovani na funkcijama također zahtijeva malo zrnastih dosada za pravilnu provedbu.

Na kraju sam zadržao ApplyByAPI dok sam većinu prikaza preoblikovao u poglede temeljene na klasama. Ovo nije bio mali posao i refaktoriranje, ali kad je to bilo učinjeno, imao sam gomilu sitnih pogleda koji su napravili ogromnu razliku. Mislim, pogledajte samo ovaj:

class ApplicationsList(ListView): model = Application template_name = "applications.html" 

To su tri retka. Moja ergonomija programera i moj život postali su puno lakši.

Prizore temeljene na nastavi možete smatrati predlošcima koji pokrivaju većinu funkcionalnosti bilo koje aplikacije koja treba. Postoje pogledi za prikaz popisa stvari, za detaljno pregledavanje stvari i uređivanje pogleda za obavljanje CRUD (Stvaranje, čitanje, ažuriranje, brisanje) operacija.

Budući da je za provedbu jednog od ovih generičkih pogleda potrebno samo nekoliko redaka koda, logika moje aplikacije postala je dramatično jezgrovita. To mi je dalo manje ponovljeni kôd, manje mjesta za nešto što bi pošlo po zlu i općenito više upravljivu aplikaciju.

Poglede temeljene na nastavi brzo je implementirati i koristiti. Ugrađeni generički pogledi temeljeni na razredima mogu zahtijevati manje posla za testiranje, jer ne trebate pisati testove za osnovni prikaz koji Django pruža. (Django radi vlastite testove za to; nije potrebno da vaša aplikacija ponovno provjerava.)

Da biste generički prikaz prilagodili svojim potrebama, možete podrazrediti generički prikaz i poništiti atribute ili metode. U mom slučaju, budući da sam trebao napisati testove samo za bilo kakve prilagodbe koje sam dodao, moje su testne datoteke dramatično postale kraće, kao i vrijeme i resursi potrebni za njihovo pokretanje.

Kada vagate između izbora koji se temelje na funkcijama ili na temelju klase, uzmite u obzir količinu prilagodbe koja je pogledu potrebna i budući rad koji će biti potreban za njezino testiranje i održavanje.

Ako je logika zajednička, možda ćete moći udariti u tlo s generičkim prikazom utemeljenim na klasi. Ako vam je potrebna dovoljna granularnost da bi je ponovno pisanje metoda osnovnog pogleda pretjerano zakompliciralo, razmislite umjesto o funkcijskom pogledu.

Django modeli

Modeli organiziraju središnje koncepte vaše Django aplikacije kako bi ih učinili fleksibilnima, robusnima i jednostavnima za rad. Ako se pametno koriste, modeli su moćan način za objedinjavanje vaših podataka u konačni izvor istine.

Kao i prikazi, Django nudi neke ugrađene vrste modela radi praktičnosti primjene osnovne provjere autentičnosti, uključujući modele User i Permission. Za sve ostalo možete stvoriti model koji odražava vaš koncept nasljeđivanjem iz roditeljske klase Model.

class StaffMember(models.Model): user = models.OneToOneField(User, on_delete=models.CASCADE) company = models.OneToOneField(Company, on_delete=models.CASCADE) def __str__(self): return self.company.name + " - " + self.user.email 

Kada izradite prilagođeni model u Djangu, podrazredite Djangovu klasu Model i iskoristite svu njegovu snagu. Svaki model koji kreirate uglavnom se preslikava na tablicu baze podataka. Svaki atribut je polje baze podataka. To vam daje sposobnost stvaranja predmeta za rad s kojima ljudi mogu bolje razumjeti.

Možete učiniti model korisnim za vas definiranjem njegovih polja. Mnogi ugradbeni tipovi polja su prikladno dostupni. To pomaže Djangu da shvati vrstu podataka, HTML widget koji će se koristiti prilikom prikazivanja obrasca, pa čak i zahtjeve za provjeru valjanosti obrasca. Ako trebate, možete napisati prilagođena polja modela.

Odnosi s bazom podataka mogu se definirati pomoću polja ForeignKey (više-prema-jednom) ili ManyToManyField (daju vam tri nagađanja). Ako to nije dovoljno, tu je i OneToOneField.  

Zajedno vam omogućuju definiranje odnosa između vaših modela s razinama složenosti ograničene samo vašom maštom. (Ovisno o vašoj mašti, ovo može, ali ne mora biti prednost.)

Dohvaćanje objekata s upitima

Koristite upravitelj svog modela ( objectsprema zadanim postavkama) za izgradnju QuerySet-a. Ovo je prikaz objekata u vašoj bazi podataka koje možete pročistiti, koristeći metode, za dohvaćanje određenih podskupova. Sve dostupne metode nalaze se u API-ju QuerySet i mogu se povezati lancima za još veću zabavu.

Post.objects.filter( type="new" ).exclude( title__startswith="Blockchain" ) 

Neke metode vraćaju nove QuerySets, poput filter()ili exclude(). Njihovim ulančavanjem možete dobiti moćne upite bez utjecaja na izvedbu, jer se QuerySets ne preuzimaju iz baze podataka dok se ne procijene. Metode kojima se procjenjuje na skup upita uključuju get(), count(), len(), list(), ili bool().

Iteriranje preko QuerySet-a također ga procjenjuje, pa izbjegavajte to činiti kad god je to moguće kako biste poboljšali izvedbu upita. Na primjer, ako samo želite znati je li objekt prisutan, možete to koristiti exists()kako biste izbjegli ponavljanje nad objektima baze podataka.

Koristite get()u slučajevima kada želite dohvatiti određeni objekt. Ova se metoda povećava MultipleObjectsReturnedako se dogodi nešto neočekivano, kao i DoesNotExistiznimka, ako, pogodite.

Ako želite dobiti objekt koji možda ne postoji u kontekstu korisnikova zahtjeva, upotrijebite prikladni get_object_or_404()ili get_list_or_404()koji povisuje Http404umjesto DoesNotExist. Ovi korisni prečaci prikladni su upravo za ovu svrhu. Da biste stvorili objekt koji ne postoji, postoji i prikladno get_or_create().

Učinkovite osnove

Sad ste se upoznali s ova tri osnovna alata za izgradnju vaše učinkovite Django aplikacije - čestitamo!

Django može učiniti puno više za vas, pa pratite buduće članke.

Ako ćete graditi na GitHubu, možda ćete htjeti postaviti moju django-sigurnosnu provjeru GitHub akcije. U međuvremenu ste na dobrom putu da napravite prekrasan softverski projekt.