Mundarija (22)
- 1. Kirish va motivatsiya
- 2. Nazariya — chuqur tushuntirish
- 2.1. Field lookup'lar
- 2.2. Q obyektlari (murakkab mantiq)
- 2.3. F ifodalari (maydonlararo)
- 2.4. Agregatlar
- 2.5. Guruhlash (values + annotate)
- 2.6. exclude, exists, count, first
- 2.7. QuerySet dangasaligi (lazy)
- 2.8. So'rov optimizatsiyasi asoslari
- 3. Tez ma'lumotnoma
- 4. Batafsil misollar
- Misol 1 — Field lookup'lar
- Misol 2 — Q va F ifodalari
- Misol 3 — Agregatlar va guruhlash
- Misol 4 — Amaliy: to'liq so'rovlar
- 5. To'g'ri va noto'g'ri tushunishlar
- 6. Keng tarqalgan xatolar va yechimlari
- 7. Integratsiya — bu bilim qayerda kerak bo'ladi
- 8. Eng yaxshi amaliyotlar
- 9. Amaliy topshiriq
- Xulosa
21.9-dars: ORM: so'rovlar
21-QISM — DJANGO · 9-dars
1. Kirish va motivatsiya
Django ORM'ning asosini (model, filter, get) ko'rdik. Endi uni chuqurroq o'rganamiz: murakkab qidiruv, mantiqiy shartlar (VA/YOKI), maydonlararo solishtirish, guruhlash va agregatlar. Django ORM — SQL'ni Python'da ifodalovchi kuchli so'rov tili. Uni yaxshi bilish — samarali, toza ma'lumot kodi.
ORM so'rovlari — Django ilovasining yuragi: har sahifa, har API ma'lumot oladi. To'g'ri so'rov — tez, aniq; noto'g'ri — sekin, ortiqcha. Bu darsda lookup'lar (__gte, __contains), Q obyektlari (murakkab mantiq), F ifodalari (maydonlararo), agregatlar (Count, Avg) va guruhlashni o'rganamiz.
Real vaziyat. Bir jamoa murakkab qidiruvni Python'da qilardi: barcha kursni olib (Kurs.objects.all()), keyin Python'da filtr (for k in ... if ...) — minglab yozuv xotiraga, sekin. Ular ORM'ga o'tdi: filter(Q(til="uz") | Q(narx__lt=100)) — baza filtrlaydi (tez, kam xotira). Agregatlarni ham (aggregate(Avg("narx"))) baza hisobladi. So'rovlar 100 barobar tezlashdi. ORM'ni to'g'ri ishlatish — samaradorlik.
Bu darsda ORM so'rovlarini — lookup, Q, F, agregat va guruhlashni o'rganamiz.
Bu darsda:
- Field lookup'lar (
__gte,__contains,__in) -
Qobyektlari (VA/YOKI mantiq) Fifodalari (maydonlararo)- Agregatlar (
Count,Avg,Sum,Max) - Guruhlash (
values+annotate) exclude,exists,count,first- QuerySet dangasaligi (lazy)
- Amaliy: to'liq so'rovlar
ℹ Misollarda Django standalone ORM bilan sinaladi.
2. Nazariya — chuqur tushuntirish
2.1. Field lookup'lar
Lookup — maydonga cheklov (maydon__lookup):
Kurs.objects.filter(narx__gte=100) # narx >= 100
Kurs.objects.filter(nom__contains="Py") # nom "Py" ni o'z ichida
Kurs.objects.filter(til__in=["uz", "en"]) # til uz yoki en| Lookup | SQL | Ma'no |
|---|---|---|
__gte, __lte |
>=, <= |
Katta/kichik teng |
__gt, __lt |
>, < |
Katta/kichik |
__contains |
LIKE %..% |
O'z ichida |
__startswith |
LIKE ..% |
Bilan boshlanadi |
__in |
IN (...) |
Ro'yxatda |
__isnull |
IS NULL |
Bo'sh |
Lookup — maydon__lookup=qiymat. Ular SQL shartlariga aylanadi (WHERE). Bu 20.8 dagi qo'lda SQL'dan ancha toza va xavfsiz (parametrlangan avtomatik).
2.2. Q obyektlari (murakkab mantiq)
filter argumentlari VA (AND) bilan bog'lanadi. YOKI (OR) uchun Q:
from django.db.models import Q
# VA (standart):
Kurs.objects.filter(til="uz", narx__lt=100) # til=uz VA narx<100
# YOKI (Q bilan):
Kurs.objects.filter(Q(til="uz") | Q(narx__gt=140)) # til=uz YOKI narx>140
# NOT:
Kurs.objects.filter(~Q(til="uz")) # til uz EMAS Q — murakkab mantiqiy shartlar: | (YOKI), & (VA), ~ (EMAS). Oddiy filter faqat VA; Q bilan YOKI va murakkab kombinatsiya. Bu murakkab qidiruv uchun zarur.
2.3. F ifodalari (maydonlararo)
F — bir maydonni boshqa maydon bilan solishtirish:
from django.db.models import F
# sotildi > narx / 2 (ikki maydon):
Kurs.objects.filter(sotildi__gt=F("narx") / 2)
# maydonni oshirish (baza darajasida):
Kurs.objects.update(sotildi=F("sotildi") + 1) F — maydon qiymatini baza darajasida ishlatadi (Python'ga olmasdan). Ikki maydonni solishtirish yoki maydonni o'ziga nisbatan yangilash (narx * 1.1). Bu tez va poyga holatidan xoli (atomik).
2.4. Agregatlar
Agregat — butun to'plam bo'yicha hisob (Count, Avg, Sum, Max, Min):
from django.db.models import Avg, Count, Sum, Max
Kurs.objects.aggregate(
ortacha=Avg("narx"),
jami_sotildi=Sum("sotildi"),
eng_qimmat=Max("narx"),
soni=Count("id"),
)
# → {"ortacha": 115.0, "jami_sotildi": 170, ...} aggregate — butun QuerySet bo'yicha bitta natija (o'rtacha, jami, maksimal). Baza hisobladi (tez). Bu Python'da sikl bilan hisoblashdan ancha samarali (barcha yozuvni olmasdan).
2.5. Guruhlash (values + annotate)
Guruhlash (GROUP BY) — values + annotate:
from django.db.models import Count
# til bo'yicha kurslar soni:
Kurs.objects.values("til").annotate(soni=Count("id"))
# → [{"til": "en", "soni": 2}, {"til": "uz", "soni": 2}] values("maydon").annotate(...) — maydon bo'yicha guruhlab, har guruhga agregat (GROUP BY). Bu "har til uchun nechta kurs", "har kategoriya jami narxi" kabi hisobotlar uchun.
2.6. exclude, exists, count, first
Foydali QuerySet metodlari:
| Metod | Vazifa |
|---|---|
exclude(...) |
Teskari filtr (NOT) |
count() |
Soni (samarali) |
exists() |
Bor-yo'qligi (True/False) |
first()/last() |
Birinchi/oxirgi |
values(...) |
Lug'at (tanlangan maydon) |
values_list(..., flat=True) |
Ro'yxat |
Kurs.objects.exclude(til="uz") # uz emas
Kurs.objects.filter(narx__gt=200).exists() # bormi
Kurs.objects.count() # nechta count() — SQL COUNT (barcha yozuvni olmasdan); exists() — bor-yo'qligini tez tekshiradi (len(qs) dan yaxshiroq). To'g'ri metod — samaradorlik.
2.7. QuerySet dangasaligi (lazy)
QuerySet dangasa (lazy) — kerak bo'lguncha bazaga bormaydi:
qs = Kurs.objects.filter(til="uz") # baza so'rovi YO'Q
qs = qs.filter(narx__lt=100) # hali YO'Q (zanjir)
list(qs) # ENDI baza so'rovi (bir marta) QuerySet dangasa — filter zanjiri baza so'rovi qilmaydi; faqat ishlatilganda (list, sikl, len) bir marta so'rov ketadi. Bu samarali (zanjir bir SQL'ga birlashadi) va moslashuvchan (so'rov quriladi).
2.8. So'rov optimizatsiyasi asoslari
| Yaxshi | Yomon |
|---|---|
filter() (baza) |
Python'da filtr |
count() |
len(qs) |
exists() |
if qs |
aggregate() |
Sikl bilan hisob |
values() (kerak maydon) |
Butun obyekt |
Baza ishlashi kerak, Python emas: filter, aggregate, count — baza hisobladi (tez). Python'ga barcha yozuvni olib keyin ishlash — sekin, xotiratalab. To'g'ri ORM — bazaga ishni topshiradi. (N+1 muammosi — 23.9.)
3. Tez ma'lumotnoma
from django.db.models import Q, F, Count, Avg, Sum, Max
# lookup'lar:
Kurs.objects.filter(narx__gte=100, nom__contains="Py", til__in=["uz"])
# Q (YOKI/EMAS):
Kurs.objects.filter(Q(til="uz") | Q(narx__gt=140))
Kurs.objects.filter(~Q(til="uz"))
# F (maydonlararo):
Kurs.objects.filter(sotildi__gt=F("narx") / 2)
Kurs.objects.update(sotildi=F("sotildi") + 1)
# agregat va guruh:
Kurs.objects.aggregate(ortacha=Avg("narx"), soni=Count("id"))
Kurs.objects.values("til").annotate(soni=Count("id"))
# metodlar:
qs.exclude(...) · qs.count() · qs.exists() · qs.first() · qs.values_list("nom", flat=True)Lookup'lar
__gte __lte __gt __lt · __contains __startswith · __in · __isnull4. Batafsil misollar
Misollarda Django standalone ORM bilan sinaladi.
Misol 1 — Field lookup'lar
"""field lookup'lar (__gte, __contains, __startswith, __in); WHERE shartlari; baza filtrlaydi."""
import warnings
warnings.filterwarnings("ignore")
import sys
import tempfile
import types
import django
from django.conf import settings
settings.configure(
DEBUG=False,
DATABASES={"default": {"ENGINE": "django.db.backends.sqlite3", "NAME": ":memory:"}},
INSTALLED_APPS=["wisar"],
DEFAULT_AUTO_FIELD="django.db.models.BigAutoField",
)
_app = types.ModuleType("wisar")
_app.__path__ = [tempfile.gettempdir()]
sys.modules["wisar"] = _app
django.setup()
from django.db import connection, models
class Kurs(models.Model):
nom = models.CharField(max_length=100)
narx = models.IntegerField()
til = models.CharField(max_length=10)
class Meta:
app_label = "wisar"
def main() -> None:
with connection.schema_editor() as se:
se.create_model(Kurs)
for n, p, t in [("Python", 100, "uz"), ("JavaScript", 80, "uz"), ("Go", 120, "en"), ("Rust", 150, "en")]:
Kurs.objects.create(nom=n, narx=p, til=t)
print("=== 1. __gte (>=) ===")
print(f" narx>=120: {list(Kurs.objects.filter(narx__gte=120).values_list('nom', flat=True))}")
print("\n=== 2. __contains (LIKE) ===")
print(f" nom 'Script': {list(Kurs.objects.filter(nom__contains='Script').values_list('nom', flat=True))}")
print("\n=== 3. __startswith ===")
print(f" nom 'R' bilan: {list(Kurs.objects.filter(nom__startswith='R').values_list('nom', flat=True))}")
print("\n=== 4. __in (ro'yxatda) ===")
print(f" til uz: {list(Kurs.objects.filter(til__in=['uz']).values_list('nom', flat=True))}")
print(" ⭐ lookup (maydon__lookup) — SQL WHERE (baza filtrlaydi)")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. __gte (>=) ===
narx>=120: ['Go', 'Rust']
=== 2. __contains (LIKE) ===
nom 'Script': ['JavaScript']
=== 3. __startswith ===
nom 'R' bilan: ['Rust']
=== 4. __in (ro'yxatda) ===
til uz: ['Python', 'JavaScript']
⭐ lookup (maydon__lookup) — SQL WHERE (baza filtrlaydi)Nima ko'rsatdi: 2.1, 2.8-bo'limlar.
Misol 2 — Q va F ifodalari
"""Q obyektlari (YOKI |, EMAS ~); F ifodalari (maydonlararo, baza darajasida yangilash)."""
import warnings
warnings.filterwarnings("ignore")
import sys
import tempfile
import types
import django
from django.conf import settings
settings.configure(
DEBUG=False,
DATABASES={"default": {"ENGINE": "django.db.backends.sqlite3", "NAME": ":memory:"}},
INSTALLED_APPS=["wisar"],
DEFAULT_AUTO_FIELD="django.db.models.BigAutoField",
)
_app = types.ModuleType("wisar")
_app.__path__ = [tempfile.gettempdir()]
sys.modules["wisar"] = _app
django.setup()
from django.db import connection, models
from django.db.models import F, Q
class Kurs(models.Model):
nom = models.CharField(max_length=100)
narx = models.IntegerField()
til = models.CharField(max_length=10)
sotildi = models.IntegerField(default=0)
class Meta:
app_label = "wisar"
def main() -> None:
with connection.schema_editor() as se:
se.create_model(Kurs)
for n, p, t, s in [("Python", 100, "uz", 50), ("Go", 120, "en", 30), ("Rust", 150, "en", 10), ("Java", 90, "uz", 80)]:
Kurs.objects.create(nom=n, narx=p, til=t, sotildi=s)
print("=== 1. Q — YOKI (|) ===")
natija = Kurs.objects.filter(Q(til="uz") | Q(narx__gt=140))
print(f" til=uz YOKI narx>140: {sorted(natija.values_list('nom', flat=True))}")
print("\n=== 2. Q — EMAS (~) ===")
natija = Kurs.objects.filter(~Q(til="uz"))
print(f" til uz EMAS: {sorted(natija.values_list('nom', flat=True))}")
print("\n=== 3. F — maydonlararo ===")
natija = Kurs.objects.filter(sotildi__gt=F("narx") - 70)
print(f" sotildi > narx-70: {sorted(natija.values_list('nom', flat=True))}")
print("\n=== 4. F — baza darajasida yangilash ===")
Kurs.objects.update(sotildi=F("sotildi") + 1)
print(f" hammaga +1 sotildi: {sorted(Kurs.objects.values_list('nom', 'sotildi'))}")
print(" ⭐ Q — YOKI/EMAS mantiq; F — maydonlararo (baza darajasida)")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. Q — YOKI (|) ===
til=uz YOKI narx>140: ['Java', 'Python', 'Rust']
=== 2. Q — EMAS (~) ===
til uz EMAS: ['Go', 'Rust']
=== 3. F — maydonlararo ===
sotildi > narx-70: ['Java', 'Python']
=== 4. F — baza darajasida yangilash ===
hammaga +1 sotildi: [('Go', 31), ('Java', 81), ('Python', 51), ('Rust', 11)]
⭐ Q — YOKI/EMAS mantiq; F — maydonlararo (baza darajasida)Nima ko'rsatdi: 2.2, 2.3-bo'limlar.
Misol 3 — Agregatlar va guruhlash
"""agregatlar (Count, Avg, Sum, Max); aggregate (butun to'plam); values+annotate (guruhlash, GROUP BY)."""
import warnings
warnings.filterwarnings("ignore")
import sys
import tempfile
import types
import django
from django.conf import settings
settings.configure(
DEBUG=False,
DATABASES={"default": {"ENGINE": "django.db.backends.sqlite3", "NAME": ":memory:"}},
INSTALLED_APPS=["wisar"],
DEFAULT_AUTO_FIELD="django.db.models.BigAutoField",
)
_app = types.ModuleType("wisar")
_app.__path__ = [tempfile.gettempdir()]
sys.modules["wisar"] = _app
django.setup()
from django.db import connection, models
from django.db.models import Avg, Count, Max, Sum
class Kurs(models.Model):
nom = models.CharField(max_length=100)
narx = models.IntegerField()
til = models.CharField(max_length=10)
class Meta:
app_label = "wisar"
def main() -> None:
with connection.schema_editor() as se:
se.create_model(Kurs)
for n, p, t in [("Python", 100, "uz"), ("Go", 120, "en"), ("Rust", 150, "en"), ("Java", 90, "uz")]:
Kurs.objects.create(nom=n, narx=p, til=t)
print("=== 1. aggregate (butun to'plam) ===")
stat = Kurs.objects.aggregate(ortacha=Avg("narx"), jami=Sum("narx"), eng_qimmat=Max("narx"), soni=Count("id"))
print(f" o'rtacha: {stat['ortacha']}, jami: {stat['jami']}")
print(f" eng qimmat: {stat['eng_qimmat']}, soni: {stat['soni']}")
print("\n=== 2. Guruhlash (til bo'yicha soni) ===")
guruh = Kurs.objects.values("til").annotate(soni=Count("id")).order_by("til")
print(f" {list(guruh)}")
print("\n=== 3. Guruhlash (til bo'yicha o'rtacha narx) ===")
guruh = Kurs.objects.values("til").annotate(ortacha=Avg("narx")).order_by("til")
print(f" {list(guruh)}")
print("\n=== 4. annotate + filter ===")
guruh = Kurs.objects.values("til").annotate(soni=Count("id")).filter(soni__gte=2)
print(f" 2+ kursli tillar: {[g['til'] for g in guruh]}")
print(" ⭐ aggregate — butun to'plam; values+annotate — guruhlash (GROUP BY)")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. aggregate (butun to'plam) ===
o'rtacha: 115.0, jami: 460
eng qimmat: 150, soni: 4
=== 2. Guruhlash (til bo'yicha soni) ===
[{'til': 'en', 'soni': 2}, {'til': 'uz', 'soni': 2}]
=== 3. Guruhlash (til bo'yicha o'rtacha narx) ===
[{'til': 'en', 'ortacha': 135.0}, {'til': 'uz', 'ortacha': 95.0}]
=== 4. annotate + filter ===
2+ kursli tillar: ['en', 'uz']
⭐ aggregate — butun to'plam; values+annotate — guruhlash (GROUP BY)Nima ko'rsatdi: 2.4, 2.5-bo'limlar.
Misol 4 — Amaliy: to'liq so'rovlar
Real qidiruv/hisobot tizimini quramiz: filtr zanjiri, Q mantiq, agregatlar va samarali metodlar. Bu — Django ilovasidagi ma'lumot so'rovlarining namunasi.
"""to'liq so'rovlar: filtr zanjiri, Q, agregat, exclude/exists/count/first, values_list; samarali ORM."""
import warnings
warnings.filterwarnings("ignore")
import sys
import tempfile
import types
import django
from django.conf import settings
settings.configure(
DEBUG=False,
DATABASES={"default": {"ENGINE": "django.db.backends.sqlite3", "NAME": ":memory:"}},
INSTALLED_APPS=["wisar"],
DEFAULT_AUTO_FIELD="django.db.models.BigAutoField",
)
_app = types.ModuleType("wisar")
_app.__path__ = [tempfile.gettempdir()]
sys.modules["wisar"] = _app
django.setup()
from django.db import connection, models
from django.db.models import Avg, Q
class Kurs(models.Model):
nom = models.CharField(max_length=100)
narx = models.IntegerField()
til = models.CharField(max_length=10)
daraja = models.CharField(max_length=20)
class Meta:
app_label = "wisar"
def main() -> None:
with connection.schema_editor() as se:
se.create_model(Kurs)
malumot = [
("Python", 100, "uz", "boshlangich"),
("JavaScript", 80, "uz", "boshlangich"),
("Go", 120, "en", "orta"),
("Rust", 150, "en", "yuqori"),
("Java", 90, "uz", "orta"),
]
for n, p, t, d in malumot:
Kurs.objects.create(nom=n, narx=p, til=t, daraja=d)
print("=== 1. Filtr zanjiri ===")
natija = Kurs.objects.filter(til="uz").filter(narx__lt=100).order_by("narx")
print(f" uz va narx<100: {list(natija.values_list('nom', 'narx'))}")
print("\n=== 2. Q — murakkab qidiruv ===")
natija = Kurs.objects.filter(Q(daraja="orta") | Q(narx__gte=150))
print(f" orta YOKI qimmat: {sorted(natija.values_list('nom', flat=True))}")
print("\n=== 3. Agregat va guruh ===")
print(f" o'rtacha narx: {Kurs.objects.aggregate(o=Avg('narx'))['o']}")
guruh = list(Kurs.objects.values("til").annotate(soni=models.Count("id")).order_by("til"))
print(f" til bo'yicha: {guruh}")
print("\n=== 4. Samarali metodlar ===")
print(f" jami: {Kurs.objects.count()}")
print(f" qimmat (>200) bormi: {Kurs.objects.filter(narx__gt=200).exists()}")
print(f" eng arzon: {Kurs.objects.order_by('narx').first().nom}")
print(f" uz emas: {Kurs.objects.exclude(til='uz').count()} ta")
print(" ⭐ filtr zanjiri + Q + agregat + count/exists/first — samarali")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. Filtr zanjiri ===
uz va narx<100: [('JavaScript', 80), ('Java', 90)]
=== 2. Q — murakkab qidiruv ===
orta YOKI qimmat: ['Go', 'Java', 'Rust']
=== 3. Agregat va guruh ===
o'rtacha narx: 108.0
til bo'yicha: [{'til': 'en', 'soni': 2}, {'til': 'uz', 'soni': 3}]
=== 4. Samarali metodlar ===
jami: 5
qimmat (>200) bormi: False
eng arzon: JavaScript
uz emas: 2 ta
⭐ filtr zanjiri + Q + agregat + count/exists/first — samaraliNima ko'rsatdi: 2.1–2.8-bo'limlar.
5. To'g'ri va noto'g'ri tushunishlar
| Noto'g'ri fikr | To'g'risi |
|---|---|
| "Python'da filtr" | ORM (baza) — tez |
"filter YOKI qiladi" |
VA; YOKI uchun Q |
| "Maydonlararo Python'da" | F (baza darajasida) |
| "Agregatni sikl bilan" | aggregate (baza) |
"len(qs) bilan sanash" |
count() |
"if qs bilan tekshiruv" |
exists() |
| "QuerySet darrov so'rov" | Dangasa (ishlatilganda) |
| "Butun obyekt kerak" | values (kerak maydon) |
6. Keng tarqalgan xatolar va yechimlari
1. Python'da filtr (baza o'rniga)
[k for k in Kurs.objects.all() if k.narx > 100] # ⚠️ hammasi xotiraga
Kurs.objects.filter(narx__gt=100) # ✅ baza2. YOKI uchun oddiy filter
Kurs.objects.filter(til="uz", til="en") # ⚠️ mumkin emas (VA)
Kurs.objects.filter(Q(til="uz") | Q(til="en")) # ✅ YOKI3. len(qs) bilan sanash
len(Kurs.objects.all()) # ⚠️ hammasi olinadi
Kurs.objects.count() # ✅ COUNT4. Maydonlarni Python'da solishtirish
[k for k in ... if k.sotildi > k.narx] # ⚠️
Kurs.objects.filter(sotildi__gt=F("narx")) # ✅ F5. get bir necha natijada
Kurs.objects.get(til="uz") # ⚠️ MultipleObjectsReturned
Kurs.objects.filter(til="uz") # ✅ filter (ko'p)6. Agregatni sikl bilan
sum(k.narx for k in Kurs.objects.all()) # ⚠️ hammasi
Kurs.objects.aggregate(Sum("narx")) # ✅7. Yangilashni sikl bilan (poyga xavfi)
for k in ...: k.sotildi += 1; k.save() # ⚠️ sekin, poyga
Kurs.objects.update(sotildi=F("sotildi") + 1) # ✅ atomik7. Integratsiya — bu bilim qayerda kerak bo'ladi
- 21.3-dars (o'tilgan): model — so'rov manbai
- 21.10-dars: ORM bog'lanishlar —
ForeignKey,join - 23.1/23.2-dars: SQL —
WHERE,JOIN,GROUP BY - 23.9-dars: N+1 muammosi —
select_related - 20.8-dars (o'tilgan): qo'lda SQL — taqqoslash
8. Eng yaxshi amaliyotlar
Bazada filtrlang (Python'da emas).
YOKI/murakkab mantiq uchun
Qishlating.Maydonlararo
Fishlating (baza darajasida).Agregat uchun
aggregate/annotate(sikl emas).count()/exists()—len/ifo'rniga.Faqat kerak maydonni oling (
values,only).Ommaviy yangilashda
update(F(...))(atomik).QuerySet dangasaligini biling (kerak bo'lganda so'rov).
9. Amaliy topshiriq
Vazifa 1: Bashorat qiling
1. # lookup nima (__gte)?
2. # filter VA yoki YOKI?
3. # Q nima uchun?
4. # F nima uchun?
5. # aggregate nima?
6. # values+annotate nima?
7. # count va len farqi?
8. # exists nima?
9. # QuerySet dangasami?
10. # __contains nima?
11. # ~Q nima?
12. # baza yoki Python filtri?Javoblar
- Maydonga cheklov (
narx>=) - VA (AND)
- YOKI/murakkab mantiq (
|,~) - Maydonlararo (baza darajasida)
- Butun to'plam bo'yicha hisob (o'rtacha, jami)
- Guruhlash (
GROUP BY) count— SQL COUNT;len— hammasi olinadi- Bor-yo'qligini tez tekshiradi
- Ha (ishlatilganda so'rov)
LIKE %..%(o'z ichida)- EMAS (NOT)
- Baza (tez, kam xotira)
Vazifa 2: Xatolarni tuzating
1. [k for k in Kurs.objects.all() if k.narx > 100] # baza
2. Kurs.objects.filter(til="uz", til="en") # YOKI
3. len(Kurs.objects.all()) # sanash
4. for k in ...: k.sotildi += 1; k.save() # atomik
5. sum(k.narx for k in Kurs.objects.all()) # agregatJavoblar
1. Kurs.objects.filter(narx__gt=100)
2. Kurs.objects.filter(Q(til="uz") | Q(til="en"))
3. Kurs.objects.count()
4. Kurs.objects.update(sotildi=F("sotildi") + 1)
5. Kurs.objects.aggregate(Sum("narx"))Vazifa 3: Qidiruv tizimi
Mahsulot qidiruvi:
- Lookup'lar (
__gte,__contains,__in) - Filtr zanjiri
- Saralash va sahifalash
- Natijalarni test
Vazifa 4: Murakkab mantiq (Q)
Q bilan qidiruv:
- YOKI (
|), VA (&), EMAS (~) - Murakkab kombinatsiya
- Har holatni test
- SQL bilan taqqoslash
Vazifa 5: Hisobotlar (agregat)
Hisobot tizimi:
aggregate(o'rtacha, jami, maksimal)values+annotate(guruhlash)annotate+filter- Natijalarni tekshirish
Vazifa 6: Samaradorlik
Samarali so'rovlar:
count/existsvslen/ifFbilan atomik yangilashvalues/onlybilan kam ma'lumot- Taqqoslash (samaradorlik)
Vazifa 7: O'ylash
Django ORM so'rovlari baza darajasida ishlaydi — filter, aggregate, count SQL'ga aylanib, baza hisobladi (Python'ga barcha yozuvni olmasdan). Bu "hisobni ma'lumotga yaqin bajarish" (ma'lumotni kodga olib kelish o'rniga) tamoyili. Ishni ma'lumot turgan joyda (bazada) bajarishning afzalligi nima, va bu tamoyil (ma'lumotni harakatlantirmaslik) katta ma'lumotda nima uchun ayniqsa muhim?
Javob
Qisqa javob: ORM so'rovlari SQL'ga aylanib, baza ma'lumot turgan joyda hisoblaydi — filtr, agregat, guruhlash bazada. Buning aksi — barcha ma'lumotni Python'ga olib (all()), keyin Python'da ishlash. Bazada ishlash afzal, chunki: kam ma'lumot ko'chiriladi (faqat natija, barcha yozuv emas), tez (baza optimizatsiyalangan, indekslar), kam xotira (Python'da minglab yozuv turmaydi). Katta ma'lumotda bu ayniqsa muhim: million yozuvni Python'ga olib bo'lmaydi (xotira), lekin baza uni tez filtrlaydi/hisoblaydi. "Ishni ma'lumotga yaqin bajar" — ma'lumotni harakatlantirma.
1. Bazada vs Python'da
| Bazada (yaxshi) | Python'da (yomon) |
|---|---|
filter, aggregate |
all() + sikl |
| Faqat natija ko'chiriladi | Barcha yozuv |
| Tez (indeks) | Sekin |
| Kam xotira | Ko'p xotira |
2. "Ishni ma'lumotga yaqin bajar"
Ma'lumot bazada — hisobni shu joyda bajar (SQL). Ma'lumotni Python'ga olib kelib ishlash — ko'chirish (sekin, xotiratalab).
3. Katta ma'lumotda
Million yozuv:
- Python'ga olib bo'lmaydi (xotira yetmaydi)
- Baza uni tez filtrlaydi (indeks, optimizatsiya)
- Faqat natija (masalan, o'rtacha) qaytadi
4. "Ma'lumotni harakatlantirmaslik" boshqa joyda
| Soha | Ma'lumotga yaqin ish |
|---|---|
| ORM/SQL | Bazada hisob |
| MapReduce | Ma'lumot turgan nodeda |
| Kesh | Yaqin saqlash |
| CDN | Foydalanuvchiga yaqin |
5. Muhandislik saboqlari
- Ishni ma'lumot turgan joyda bajar
- Ma'lumotni harakatlantirma (ko'chirish — qimmat)
- Baza filtr/agregatda kuchli (foydalan)
- Katta ma'lumotda — hisob ma'lumotga yaqin
6. Xulosa
- ORM — bazada ishlaydi (SQL)
- Ma'lumotni Python'ga olma (kerak natijani ol)
- Bazada ish — tez, kam xotira
- "Ma'lumotga yaqin hisob" — katta ma'lumotda zarur
Nimani mustahkamlaydi: 2.1–2.8-bo'limlar.
Xulosa
Bu darsda Django ORM so'rovlarini chuqurroq o'rgandik.
Eng muhim uch fikr:
Lookup'lar,
QvaF. Field lookup'lar (maydon__lookup=qiymat) SQLWHEREshartlariga aylanadi:__gte/__lte(oralik),__contains/__startswith(matn),__in(ro'yxat),__isnull(bo'sh).filterargumentlari VA bilan bog'lanadi; YOKI va murakkab mantiq uchunQobyektlari (|,&,~).Fifodalari — maydonni boshqa maydon bilan solishtirish yoki maydonni o'ziga nisbatan yangilash (baza darajasida, atomik).Agregatlar va guruhlash.
aggregate— butun QuerySet bo'yicha bitta natija (Avg,Sum,Max,Count) — baza hisobladi.values("maydon").annotate(...)—maydonbo'yicha guruhlab (GROUP BY), har guruhga agregat (masalan, "har til uchun nechta kurs"). Bu hisobotlar uchun samarali — Python'da sikl bilan hisoblashdan tez.Samaradorlik va dangasalik.
count()(SQL COUNT),exists()(bor-yo'qligi) —len(qs)/if qsdan yaxshiroq.values/only— faqat kerak maydonni oladi. QuerySet dangasa (lazy) —filterzanjiri faqat ishlatilganda (list, sikl) bir marta so'rov qiladi. Asosiy tamoyil — ishni bazada bajarish (Python'da emas): baza ma'lumot turgan joyda filtrlaydi/hisoblaydi, faqat natijani qaytadi — tez, kam xotira, katta ma'lumotda zarur.
Keyingi darsda ORM: bog'lanishlar ni o'rganamiz: modellar orasidagi aloqalar — ForeignKey (bir-ko'p), ManyToManyField (ko'p-ko'p), OneToOneField va bog'langan so'rovlar.
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!