Hogyan lehet hatékony nézeteket, modelleket és lekérdezéseket írni Django-ban

Kedvelem Djangót. Ez egy jól átgondolt és intuitív keret, olyan névvel, amelyet hangosan kiejteni tudok. Segítségével gyorsan felpörgethet egy hétvégi méretű projektet, és teljes körű termelési alkalmazások futtatásához is.

Mindkét dolgot megtettem, és az évek során rájöttem, hogyan lehet a Django egyes funkcióit használni a maximális hatékonyság érdekében. Ezek:

  • Osztályalapú vagy függvényalapú nézetek
  • Django modellek
  • Objektumok lekérdezése lekérdezéssel

Vizsgáljuk meg, hogy ezek az eszközök miként hozhatnak létre olyan előadó Django alkalmazást, amelyet kellemes építeni és fenntartani.

Osztályalapú vagy függvényalapú nézetek

Ne feledje, hogy Django mind Python a motorháztető alatt. Ha a nézetekről van szó, két választási lehetősége van: nézetfunkciók (néha „funkcióalapú nézetek”) vagy osztályalapú nézetek.

Évekkel ezelőtt, amikor először építettem az ApplyByAPI-t, kezdetben teljes egészében függvényalapú nézetekből állt. Ezek részletgazdag vezérlést kínálnak, és jók a komplex logika megvalósításához. Csakúgy, mint egy Python függvényben, teljes mértékben (jóban vagy rosszban is) Ön irányíthatja a nézet működését.

De nagy irányítással nagy felelősség jár, és a funkcióalapú nézetek kissé unalmasak lehetnek. Ön felel a nézet működéséhez szükséges összes módszer megírásáért - ez teszi lehetővé az alkalmazás teljes testreszabását.

Az ApplyByAPI esetében csak ritkán volt néhány olyan hely, ahol valóban szükség volt a személyre szabott funkcionalitás ilyen szintjére. Mindenhol a funkcióalapú nézetek kezdték megnehezíteni az életemet. Olyan írás, amely lényegében egy egyedi nézet a futási műveletekhez, például az adatok megjelenítése egy listaoldalon, unalmas, ismétlődő és hibára hajlamos lett.

Funkcióalapú nézeteknél meg kell találnia, hogy mely Django módszereket kell végrehajtania a kérések kezeléséhez és az adatok továbbításához a nézetekhez. Az egység tesztelése némi munkát igényel. Röviden, a funkcióalapú nézetek által kínált szemcsés vezérléshez némi szemcsés univerzum is szükséges a megfelelő megvalósításhoz.

Végül visszatartottam az ApplyByAPI-t, miközben a nézetek többségét osztályalapú nézetekké alakítottam át. Ez nem kevés munka és visszafogás volt, de amikor ez megtörtént, rengeteg apró nézetem volt, amelyek hatalmas változást hoztak. Úgy értem, csak nézze meg ezt:

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

Három sor. A fejlesztői ergonómiám és az életem sokkal könnyebbé vált.

Az osztályalapú nézetekre sablonként gondolhat, amelyek lefedik az alkalmazáshoz szükséges funkciók nagy részét. Vannak nézetek a dolgok listájának megjelenítésére, a dolgok részletes megtekintésére és a nézetek szerkesztésére a CRUD (létrehozás, olvasás, frissítés, törlés) műveletek végrehajtásához.

Mivel ezen általános nézetek egyikének végrehajtása csak néhány sor kódot igényel, az alkalmazáslogikám drámai módon tömör lett. Így kevesebb ismételt kódot kaptam, kevesebb helyet adtam valami hibáért, és általában egy jobban kezelhető alkalmazást kaptam.

Az osztályalapú nézetek gyorsan megvalósíthatók és használhatók. A beépített osztályalapú általános nézetek kevesebb munkát igényelhetnek a teszteléshez, mivel nem kell teszteket írni a Django által biztosított alapnézethez. (A Django elvégzi saját tesztjeit; nincs szükség arra, hogy az alkalmazás kétszer ellenőrizze.)

Ha általános nézetet kíván az igényeinek megfelelően módosítani, akkor alosztályba sorolhatja az általános nézetet, és felülírhatja az attribútumokat vagy módszereket. Az én esetemben, mivel csak a hozzáadott testreszabásokhoz kellett teszteket írnom, a tesztfájljaim drámai módon lerövidültek, csakúgy, mint a futtatásukhoz szükséges idő és erőforrások.

Ha mérlegeli a függvényalapú vagy osztályalapú nézetek közötti választást, vegye figyelembe a nézet igényeinek testreszabását és a jövőbeni teszteléshez és karbantartáshoz szükséges munkát.

Ha a logika közös, akkor valószínűleg egy általános osztályalapú nézettel érheti el a talajt. Ha kellő részletességre van szüksége, amely az alapnézet metódusainak újbóli megírása túl bonyolulttá tenné, fontolja meg inkább a függvényalapú nézetet.

Django modellek

A modellek úgy szervezik az Ön Django alkalmazásának központi koncepcióit, hogy rugalmasabbá, robusztusabbá és könnyebben használhatóvá váljanak. Okos felhasználás esetén a modellek hatékony módja annak, hogy az adatokat végleges igazságforrássá gyűjtsék össze.

A nézetekhez hasonlóan a Django is tartalmaz néhány beépített modelltípust az alapvető hitelesítés megvalósításának kényelme érdekében, beleértve a Felhasználói és Engedély modelleket is. Minden máshoz létrehozhat egy modellt, amely tükrözi a koncepciót, ha örökli a szülő Model osztályt.

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 

Amikor létrehoz egy egyedi modellt a Django-ban, akkor alosztályba sorolja a Django Model osztályát, és kihasználja annak minden erejét. Minden létrehozott modell általában egy adatbázistáblához tartozik. Minden attribútum egy adatbázis mező. Ez lehetővé teszi, hogy olyan tárgyakat hozzon létre, amelyekkel az emberek jobban megérthetik a munkát.

A modelleket a mezőinek definiálásával teheti hasznossá az Ön számára. Sok beépített terepi típus kényelmesen biztosított. Ezek segítenek Djangonak kitalálni az adattípust, az űrlap megjelenítésekor használandó HTML-modult, és még az űrlap-érvényesítési követelményeket is. Ha szükséges, írhat egyedi modellmezőket.

Az adatbázis-kapcsolatok meghatározhatók az ForeignKey mező (sok-az-egyhez) vagy a ManyToManyField segítségével (három találgatást adnak). Ha ezek nem elegendőek, van egy OneToOneField is.  

Ezek együttesen lehetővé teszik a modelljei közötti kapcsolatok meghatározását olyan összetettséggel, amelyet csak a képzelete korlátoz. (A képzelőerőtől függően ez előny lehet vagy nem.)

Objektumok lekérdezése lekérdezéssel

Használja a modell kezelőjét ( objectsalapértelmezés szerint) QuerySet készítéséhez. Ez az adatbázisban található objektumok reprezentációja, amelyet módszerek segítségével finomíthat egy adott részhalmaz lekéréséhez. Az összes rendelkezésre álló módszer a QuerySet API-ban található, és még szórakoztatóbbá lehet őket láncolni.

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

Egyes módszerek új QuerySets-eket adnak vissza, például filter(), vagy exclude(). Ezek láncolása hatékony lekérdezéseket eredményezhet, anélkül, hogy befolyásolná a teljesítményt, mivel a QuerySets nem kerül beolvasásra az adatbázisból, amíg ki nem értékelik őket. Módszerek, amelyek a lekérdezéskészlet közé get(), count(), len(), list()vagy bool().

A QuerySet felett történő iteráció kiértékeli azt is, ezért kerülje ezt, ahol csak lehetséges, a lekérdezés teljesítményének javítása érdekében. Például, ha csak azt szeretné tudni, hogy van-e objektum, akkor exists()elkerülheti az iterációt az adatbázis-objektumok felett.

Használja get()olyan esetekben, amikor egy adott objektumot szeretne letölteni. Ez a módszer felveti, MultipleObjectsReturnedha valami váratlan történik, valamint a DoesNotExistkivétel, ha feltételez.

If you’d like to get an object that may not exist in the context of a user’s request, use the convenient get_object_or_404() or get_list_or_404() which raises Http404 instead of DoesNotExist. These helpful shortcuts are suited to just this purpose. To create an object that doesn’t exist, there’s also the convenient get_or_create().

Efficient essentials

You’ve now got a handle on these three essential tools for building your efficient Django application – congratulations!

There’s a lot more that Django can do for you, so stay tuned for future articles.

If you’re  going to build on GitHub, you may like to set up my django-security-check GitHub Action. In the meantime, you’re well on your way to building a beautiful software project.