IlmHamroh
Python kursi/Django9/16-dars16 daqiqa
Mundarija (22)

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)
  • Q obyektlari (VA/YOKI mantiq)
  • F ifodalari (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):

python
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:

python
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:

python
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):

python
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:

python
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
python
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:

python
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

python
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 · __isnull

4. Batafsil misollar

Misollarda Django standalone ORM bilan sinaladi.

Misol 1 — Field lookup'lar

python
"""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:

text
=== 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

python
"""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:

text
=== 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

python
"""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:

text
=== 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.

python
"""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:

text
=== 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 — samarali

Nima 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)

python
[k for k in Kurs.objects.all() if k.narx > 100]   # ⚠️ hammasi xotiraga
Kurs.objects.filter(narx__gt=100)                  # ✅ baza

2. YOKI uchun oddiy filter

python
Kurs.objects.filter(til="uz", til="en")            # ⚠️ mumkin emas (VA)
Kurs.objects.filter(Q(til="uz") | Q(til="en"))     # ✅ YOKI

3. len(qs) bilan sanash

python
len(Kurs.objects.all())                            # ⚠️ hammasi olinadi
Kurs.objects.count()                               # ✅ COUNT

4. Maydonlarni Python'da solishtirish

python
[k for k in ... if k.sotildi > k.narx]             # ⚠️
Kurs.objects.filter(sotildi__gt=F("narx"))         # ✅ F

5. get bir necha natijada

python
Kurs.objects.get(til="uz")                         # ⚠️ MultipleObjectsReturned
Kurs.objects.filter(til="uz")                      # ✅ filter (ko'p)

6. Agregatni sikl bilan

python
sum(k.narx for k in Kurs.objects.all())            # ⚠️ hammasi
Kurs.objects.aggregate(Sum("narx"))                # ✅

7. Yangilashni sikl bilan (poyga xavfi)

python
for k in ...: k.sotildi += 1; k.save()             # ⚠️ sekin, poyga
Kurs.objects.update(sotildi=F("sotildi") + 1)      # ✅ atomik

7. 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

  1. Bazada filtrlang (Python'da emas).

  2. YOKI/murakkab mantiq uchun Q ishlating.

  3. Maydonlararo F ishlating (baza darajasida).

  4. Agregat uchun aggregate/annotate (sikl emas).

  5. count()/exists() — len/if o'rniga.

  6. Faqat kerak maydonni oling (values, only).

  7. Ommaviy yangilashda update(F(...)) (atomik).

  8. QuerySet dangasaligini biling (kerak bo'lganda so'rov).


9. Amaliy topshiriq

Vazifa 1: Bashorat qiling

python
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
  1. Maydonga cheklov (narx>=)
  2. VA (AND)
  3. YOKI/murakkab mantiq (|, ~)
  4. Maydonlararo (baza darajasida)
  5. Butun to'plam bo'yicha hisob (o'rtacha, jami)
  6. Guruhlash (GROUP BY)
  7. count — SQL COUNT; len — hammasi olinadi
  8. Bor-yo'qligini tez tekshiradi
  9. Ha (ishlatilganda so'rov)
  10. LIKE %..% (o'z ichida)
  11. EMAS (NOT)
  12. Baza (tez, kam xotira)

Vazifa 2: Xatolarni tuzating

python
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())            # agregat
Javoblar
python
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:

  1. Lookup'lar (__gte, __contains, __in)
  2. Filtr zanjiri
  3. Saralash va sahifalash
  4. Natijalarni test

Vazifa 4: Murakkab mantiq (Q)

Q bilan qidiruv:

  1. YOKI (|), VA (&), EMAS (~)
  2. Murakkab kombinatsiya
  3. Har holatni test
  4. SQL bilan taqqoslash

Vazifa 5: Hisobotlar (agregat)

Hisobot tizimi:

  1. aggregate (o'rtacha, jami, maksimal)
  2. values + annotate (guruhlash)
  3. annotate + filter
  4. Natijalarni tekshirish

Vazifa 6: Samaradorlik

Samarali so'rovlar:

  1. count/exists vs len/if
  2. F bilan atomik yangilash
  3. values/only bilan kam ma'lumot
  4. 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

  1. Ishni ma'lumot turgan joyda bajar
  2. Ma'lumotni harakatlantirma (ko'chirish — qimmat)
  3. Baza filtr/agregatda kuchli (foydalan)
  4. Katta ma'lumotda — hisob ma'lumotga yaqin

6. Xulosa

  1. ORM — bazada ishlaydi (SQL)
  2. Ma'lumotni Python'ga olma (kerak natijani ol)
  3. Bazada ish — tez, kam xotira
  4. "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:

  1. Lookup'lar, Q va F. Field lookup'lar (maydon__lookup=qiymat) SQL WHERE shartlariga aylanadi: __gte/__lte (oralik), __contains/__startswith (matn), __in (ro'yxat), __isnull (bo'sh). filter argumentlari VA bilan bog'lanadi; YOKI va murakkab mantiq uchun Q obyektlari (|, &, ~). F ifodalari — maydonni boshqa maydon bilan solishtirish yoki maydonni o'ziga nisbatan yangilash (baza darajasida, atomik).

  2. Agregatlar va guruhlash. aggregate — butun QuerySet bo'yicha bitta natija (Avg, Sum, Max, Count) — baza hisobladi. values("maydon").annotate(...) — maydon bo'yicha guruhlab (GROUP BY), har guruhga agregat (masalan, "har til uchun nechta kurs"). Bu hisobotlar uchun samarali — Python'da sikl bilan hisoblashdan tez.

  3. Samaradorlik va dangasalik. count() (SQL COUNT), exists() (bor-yo'qligi) — len(qs)/if qs dan yaxshiroq. values/only — faqat kerak maydonni oladi. QuerySet dangasa (lazy) — filter zanjiri 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.

Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
21.9-dars: ORM: so'rovlar — IlmHamroh