Dasturlashda biror texnologiyani o’rganishdan oldin o’sha texnologiyaning o’zi qanday ishlashi, qanday qismlardan tashkil topganini tushunib olish o’sha texnologiyani o’rganish jarayonini ancha osonlashtiradi.
Ko’pchilik djangoni yaqinda o’rganishni boshlagan dasturchilar avval boshda ancha qiynalishadi.Bunga sabab, django qiyin(hard)ligida emas, balki murakkab(complex) ekanligida.
Qiyin – bajarishga ko’p energiya yoki bilim talab qiladigan vazifa.**Murakkab – juda ko’plab tushunarsiz, bir-biriga bog’langan qismlardan tashkil topgan vazifa.
Farqni tushunib oldingizmi? Bo’pti, ona tili darsini chetga surib, mavzuga qaytamiz.
Bu maqolada djangodagi bir qancha eng asosiy va eng ko’p ishlatiladigan componentlar va ularning bir-biriga qanday bog’langanligini ko’rib chiqamiz.
MVT
Djangoning asosini 3 ta qism – Model, View va Template tashkil qiladi.
Keling, ularni birma-bir ko’rib chiqamiz.
Djangoda MVT dizaynining ishlashi
View
Nomlanishi «ko’rinish» ma’nosini bersa ham, aslida, views ko’rinishga javob beradigan qism emas. Views django loyihaning «miyasi» sifatida ishlaydi. Mantiqiy qismlar shu yerda yoziladi. Qolgan deyarli barcha qismlar shu qism orqali biriktiriladi va view ularni nazorat qiladi.
Serverga kelgan request(so’rov)larga view javob beradi. Masalan, djangoda yozilgan saytga browser orqali «<saytnomi>/login/» qismiga request yuborsak, url dispatcher(bu haqida pastroqda) requestni tutib olib, «login/» qismi uchun javobgar viewga yuboradi. View esa requestni analiz qilib, kerakli vazifalarni bajaradi va bizga response(javob) yuboradi.
Model
Hozirda deyarli barcha web loyihalar ma’lumotlar bazasidan foydalanadi. Pythonda yozilgan serverimiz ma’lumotlar bazasi(deylik, PostgreSQLda bo’lsin) bilan aloqa o’rnatishi uchun bizga o’rtada «ko’prik» kerak bo’ladi. Django ORM biz uchun mana shu vazifani bajaradi.
Object relational mapper(ORM) – boshqa tur(masalan, ma’lumotlar bazasi)dagi ma’lumotlarni biror dasturlash tiliga obyekt sifatida o’tkazib, foydalanish imkonini beruvchi qism.
Model esa Django ORMning bir qismi. Demak, u ham bizning serverimizni database bilan bog’lashga xizmat qiladi.
Agar siz SQL tillaridan xabardor bo’lsangiz, ma’lumotlar SQL oilasidagi ma’lumotlar bazasida jadval ko’rinishida saqlanishidan xabardor bo’lsangiz kerak. SQLda biz column(ustun)lardan qolip sifatida foydalanamiz. Row(qator)larda esa o’sha qoliplardan foydalanib yaratilgan ma’lumotlar bo’ladi.
Djangoda bitta model bitta class orqali ifodalanib, u bitta «qolip», ya’ni jadvalni hosil qiladi. Uning ichidagi fieldlar databaseda ustunlarga to’g’ri keladi. Bu model classdan olingan obyektlar esa row, ya’ni qatorlarni bildiradi.
Template
Bizga response qaytarilganda browserga keladigan ma’lumot HTML, CSS va JavaScript fayllari ko’rinishida keladi(F12 ni bosib ko’ring). Bu ma’lumotlar tarkibi shartli ravishda ikki xil bo’ladi:
Tayyor shablon(qolip) va o’zgarib turadigan ma’lumotlar. Masalan, youtubeda alohida 2 ta oynada 2 xil video ochib ko’ring. E’tibor bering, sahifa dizayni, pageda qismlarning joylashgan joyi, rangi, Tepadagi «Youtube» yozuvi bir xil. Bu template(qolip) deyiladi. Lekin, ikkita pageda video, video nomi, tavsiya qilingan videolar va h.k har xil. Bu o’zgarib turadigan ma’lumotlar.
Har bir ma’lumot uchun alohida HTML kod yoza olmaymiz. Shunchaki, qolib yozib olamiz va kerakli ma’lumotlarni bu qolipdagi kerakli joylarga «yopishtirib» chiqamiz. Bu jarayon rendering deyiladi.
Tepada view bizga response qaytarishini bilib oldik. Ana shu response(aniqrog’i HTTP response) esa kerakli ma’lumotlarni tayyor templatege render qilib, keyin yuboriladi.
App
Loyiha kattalashgan sari uni alohida qismlarga ajratib, boshqarishga oson(managable) qilishga ehtiyoj tug’iladi. Bunda har bir qismning aniq vazifasi bo’lishi kerak.
Bu vazifani djangoda app’lar bajaradi. Har bir app loyihaning o’z vazifasiga ega bo’lgan qismi. Masalan, Online bozor uchun backend yozganimizda to’lovlar uchun alohida app, mahsulotlar uchun alohida app, foydalanuvchilar uchun alohida app va h.k. qilishimiz mumkin. Shunda loyihamiz tushunishga va boshqarishga osonroq bo’ladi.
Djangoda har bitta app o’zining MVT dizayniga ega. Ya’ni har bir appning ichida alohida biz yuqorida ko’rib chiqqan model, view va template bor.
Django loyihaning tarkibidagi alohida applar
URL dispatcher
Views requestlarni qabul qilib, response qaytarishini bilib oldik. Lekin, unga qaysi request aynan qaysi viewga murojat qilishini biladigan qism – url dispatcher kerak. Aynan mana shu qism birinchi bo’lib clientdan kelgan requestni kutib oladi va request kelgan URL manziliga qarab kerakli viewga o’tkazib yuboradi. Demak, url dispatcher requestlarni kerakli viewga yetkazib beradi. Url dispatcher url pattern yoki «path»lardan tashkil topgan. Qisqasi, dispatcher requestlarni kutib oladigan manzillar. Masalan, «login/» bu url pattern. Unga bitta view biriktiriladi va har safar client «<sayt nomi>/login/» qismiga request yuborganda dispatcher uni biriktirilgan viewga yuboradi. Vazifasiga qarab url patternlarni 2 turga ajratish mumkin: to’g’ridan-to’g’ri biror viewga yuboradigan va boshqa url dispatcherga yuboradigan.
Project yaratilgan vaqtda loyiha konfiguratsiyalari turgan folderda url dispatcher avtomatik yaratiladi. Qulaylik uchun odatda, har bir app ichida ham alohida dispatcher yaratilib, bosh dispatcherga ulanadi.
Demak, o’rganganlarimizni bir joyga yig’ib olsak.
Siz browser orqali serverga request yubordingiz. Serverdagi dispatcher requestni tutib oladi va kerakli viewga yuboradi. View esa kerakli amallarni bajarib, zarur bo’lsa models orqali ma’lumotlar bazasiga murojaat qiladi. Keyin ma’lumotlarni kerakli templatega qo’yib, sizga response ko’rinishida yuboradi. Davom etamiz.
Form
Ba’zida foydalanuvchidan ma’lumot olib, o’sha ma’lumot ustida ishlash kerak bo’ladi. Masalan, user ro’yxatdan o’tayotganda undan name, password, email va h.k yuborishni so’raymiz. Agar siz HTML formlardan xabardor bo’lsangiz, buni yaxshi bilasiz.
Django formlar esa xuddi shu formlarning mantiqiy davomi, faqat frontendda emas, backendda yoziladi.
Formlarni qutilarga o’xshatish mumkin. Siz qutini bo’sh holda(ko’pincha) template orqali clientga yuborasiz. Client esa bu qutiga kerakli ma’lumotlarni solib, sizga, ya’ni backendga qaytarib beradi. Siz esa ma’lumotlar solingan qutini ochib, ichida kelgan ma’lumotlarni olasiz.
Djangoda 2 xil turdagi formlar bor. Bu yerda shu haqida qisqacha yozganman.
API
Biz tepada server side rendering, ya’ni frontend qismini ham backendda yozishni ko’rdik. Lekin hozirda aksariyat web dasturlarda backend va frontend qismlari alohida yoziladi.
Frontenddan tashqari, backend serveridan android, desktop applicationlar yoki telegram botlar va h.k.lar foydalanishi mumkin. Masalan, siz OLXning sayti, mobil/IOS ilovasi yoki telegram boti orqali ishlatishingiz mumkin. Lekin bularning barchasi bitta backend server bilan ma’lumot almashadi.
Bu jarayonda bizga API yordamga keladi. U bizga ma’lumot almashish uchun ko’prik vazifasini bajaradi. APIning o’zi esa endpointlardan tashkil topgan. Endpoint biz har kuni ishlatadigan «rozetka»(o’zbekchasini topa olmadim)ga o’xshash narsa. Client unga ulanib, ma’lumot almashadi, xuddi televizor elektrga ulanganidek.
API orqali ma’lumot almashish
Serializer
O’zbek nemischani, nemis esa o’zbekchani bilmaydi. Lekin ikkalasi ham ingliz tilini bilsa, bir-biri bilan bemalol ingliz tilida gaplashishi mumkin.
Tasavvur qiling, Javada yozilgan android dastur bizning Pythonda yozilgan serverimizdan ma’lumot olmoqchi. Muammo shundaki, ular bir-birini to’g’ridan-to’g’ri tushunda olmaydi. Demak, API orqali ma’lumot almashganda hamma tushunadigan, standart formatdan foydalanish kerak. Hozirda ko’plab APIlar ma’lumot almashish uchun JSON formatidan foydalanadi. Serializer esa Python va JSON o’rtasida(bu xususiy hol) ma’lumotlarni bir turdan boshqa turga o’tkazadi.
Django Rest Frameworkda 2 turdagi asosiy serializer bor. Maqolaning formlar haqidagi qismida berilgan linkni ko’rgan bo’lsangiz, bu turlarning vazifasini taxminan topdingiz.
Model, form va serializer ishlashi jihatidan bir-biriga o’xshash. Uchalasi ham ma’lumotni bir turdan boshqa turga o’tkazishga yordam beradi.
Model SQL orqali database bilan,
form HTML orqali client bilan,
serializer JSON orqali API bilan ma’lumot almashishni ta’minlaydi.
Migration
Ma’lumotlar bazasi dizaynga o’zgarish kiritilganda kelajakdagi xatoliklarning oldini olish yoki yangi xususiyatlar qo’shish uchun bu o’zgarishlarni yozib borish kerak bo’ladi.
Har bir mana shunday yozilgan o’zgarish migration deyiladi.
Masalan, bazaga kiritilgan o’zgarish xatolik keltirib chiqarsa yozib qo’yilgan migrationlarni qarab, qaysi o’zgarish xatolik chiqargan bo’lsa, o’sha o’zgarishdan oldingi migrationga qaytarib qo’yishimiz mumkin.
Djangodagi bu ikki command boshda ko’pchilikka tushunarsiz bo’ladi:
makemigrations – bazaning hozirgi shakli va o’zgartirish rejalashtirilgan shaklini taqqoslab, farqlarni aniqlaydi, hozirgi ma’lumotlar yangi strukturaga mos kelishini tekshiradi va o’zgarishlarni ko’rsatadigan migration fayl yozadi.
migrate – tayyor bo’lgan migration fayldagi o’zgarishlarni ma’lumotlar bazasida qo’llaydi.
Static Files
Deylik, siz «/login/» pagega request yubordingiz(shu pageni rosa ovora qildik bugun :-).
Requests viewga yetib borgach, u yerda qayta ishlanadi va view response yuboradi. E’tibor bering, bu responseni view o’zi ishlab chiqib, yuborayapti.
Lekin u response tarkibida faqat HTML kod bor, sababi templatening o’zida HTML kodlar bor. JS yoki CSS kodlari esa templatega faqat chaqirilgan, lekin templatening ichida emas. Demak, view yuborgan responseda hali CSS va JS qismlari yo’q.
Shu response bizning browserimizga yetib kelishi bilan, browserimiz uni o’qishni boshlaydi. Qarab ko’rsa-ki, u chaqirgan CSS va JS fayllar hali yo’q. Shunda browser yana qaytadan serverga request yuborib, kerakli fayllarni so’raydi. Fayl so’ziga e’tibor bering.
Lekin bu safar request viewgacha yetib kelmaydi. Sababi, bu request tepadagidek qayta ishlab, biror narsani hisoblab, databasedan biror ma’lumot olishni talab qilmaydi.
Unga faqat server xotirasida, ma’lum manzilda turgan fayl kerak. Biz esa viewni bezovta ham qilmay, so’raganini berib yuboramiz.
Mana shu turdagi, ya’ni qayta ishlanmay, o’z holicha xotiradan olinib response ko’rinishida yuboriladigan fayllar static deyiladi.
Development jarayonida djangoning o’z serveri static filelarni ham yetkazib bersa-da, loyiha tayyor bo’lib, productionga qo’yilayotganda bu tavsiya qilinmaydi.
O’rniga, boshqa web server, masalan, Nginx ishlatish tavsiya qilinadi.
U esa requestni url dispatcherdan ham oldin kutib oladi.
Ko’pchilik djangoni yangi o’rganishni boshlaganlar odatda, official documentationsni o’qishni yoqtirishmaydi. Documentation yozayotganda djangoni ishlab chiqqan dasturchilar oldida 2 xil yo’l bor edi: Yo djangoning qulayligini ko’rsatish, yoki to’la kuchini ko’rsatish. Ikkalasini bittada qilish deyarli ilojsiz. Ular ikkinchi yo’lni tanlashdi.
Shuning uchun yangilar uchun django documentation o’ta tushunarsiz va qiyin ko’rinadi. Shuning uchun boshqa tutoriallarni ma’qul ko’rishadi.
Lekin django bo’yicha bilimlaringiz oshib borgan sari django documentation qanchalik foydali, zo’r yozilganini his qilasiz.
Shu yergacha o’qib kelgan bo’lsangiz, demak maqola yaxshi chiqibdi deb o’ylayman.
Bu maqola django olamiga endi kirib kelayotganlar uchun yozildi.
Maqola bo’yicha savol yoki takliflaringiz bo’lsa, @djangouzb , @python_uz guruhlarida yoki shaxsiy accountimga yozishingiz mumkin.
Muallif: Bobosher Musurmonov