💻 Примеры: Django ORM запросы

К оглавлению урока

⚡ Кратко — ключевые примеры

from store.models import Book
from django.db.models import Q

# Создание
book = Book.objects.create(title="1984", author="Orwell", published_date="1949-06-08", price=20)

# Чтение
all_books = Book.objects.all()
cheap = Book.objects.filter(price__lt=20)
book = Book.objects.get(title="1984")  # ровно 1 запись

# Q-объекты
result = Book.objects.filter(Q(price__lt=20) | Q(is_bestseller=True))

Пример 0. Модели

Все примеры используют следующие модели (файл store/models.py):

from django.db import models

class Book(models.Model):
    title = models.CharField(max_length=100)
    author = models.CharField(max_length=50)
    published_date = models.DateField()
    price = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True)
    is_bestseller = models.BooleanField(default=False)

    def __str__(self):
        return f"{self.title} by {self.author}"

Пример 1. Django Shell

# Запуск
python manage.py shell

# Импорт моделей
from store.models import Book
from django.db.models import Q
from django.core.exceptions import ObjectDoesNotExist, MultipleObjectsReturned

Пример 2. Создание записей

# Метод create() — один шаг
book1 = Book.objects.create(
    title="The Great Gatsby",
    author="F. Scott Fitzgerald",
    published_date="1925-04-10",
    price=15
)
print(book1.id)  # например, 1

# Метод save() — с промежуточным изменением
book2 = Book(
    title="1984",
    author="George Orwell",
    published_date="1949-06-08",
    price=20
)
book2.is_bestseller = True   # изменение перед сохранением
book2.save()
print(book2.id)  # например, 2

# bulk_create — несколько записей за один SQL-запрос
books_to_add = [
    Book(title="Brave New World", author="Aldous Huxley",
         published_date="1932-08-01", price=18),
    Book(title="Fahrenheit 451", author="Ray Bradbury",
         published_date="1953-10-19", price=12),
]
Book.objects.bulk_create(books_to_add)

Пример 3. Чтение всех записей

# all() — все записи
all_books = Book.objects.all()
for book in all_books:
    print(book.title)

# first() / last()
first_book = Book.objects.all().first()
last_book = Book.objects.all().last()
print(f"Первая: {first_book}, Последняя: {last_book}")

# count() / exists()
count = Book.objects.all().count()
print(f"Всего книг: {count}")

print(Book.objects.filter(is_bestseller=True).exists())  # True/False

Пример 4. values() и values_list()

# values() — QuerySet словарей
books_dicts = Book.objects.all().values('title', 'author')
for b in books_dicts:
    print(f"{b['title']} — {b['author']}")

# values_list() — QuerySet кортежей
titles = Book.objects.all().values_list('title', flat=True)
print(list(titles))  # ['The Great Gatsby', '1984', ...]

Пример 5. Метод get()

from django.core.exceptions import ObjectDoesNotExist, MultipleObjectsReturned

# Поиск по уникальному ID
try:
    book = Book.objects.get(id=1)
    print(f"Найдена: {book.title}")
except ObjectDoesNotExist:
    print("Книга не найдена.")
except MultipleObjectsReturned:
    print("Найдено несколько записей.")

# Поиск по нескольким полям
try:
    book = Book.objects.get(
        title="The Great Gatsby",
        author="F. Scott Fitzgerald"
    )
    print(book)
except ObjectDoesNotExist:
    print("Не найдена.")

Пример 6. filter() и exclude()

# filter() — выбрать
bestsellers = Book.objects.filter(is_bestseller=True)

# exclude() — исключить
non_bestsellers = Book.objects.exclude(is_bestseller=True)

# Цепочки
result = Book.objects.filter(
    is_bestseller=True
).exclude(
    published_date__lt="2000-01-01"
).order_by('title')

Пример 7. Lookups

# exact / iexact
Book.objects.filter(title__exact="The Great Gatsby")
Book.objects.filter(title__iexact="the great gatsby")

# contains / icontains
Book.objects.filter(title__contains="Gatsby")
Book.objects.filter(author__icontains="orwell")

# startswith / endswith
Book.objects.filter(title__startswith="The")
Book.objects.filter(title__iendswith="gatsby")

# in
Book.objects.filter(id__in=[1, 2, 3])

# числа и даты
Book.objects.filter(price__gt=10)
Book.objects.filter(price__lte=20)
Book.objects.filter(published_date__gte="2000-01-01")

# isnull
Book.objects.filter(price__isnull=True)

# range
Book.objects.filter(
    published_date__range=["2020-01-01", "2023-12-31"]
)

Пример 8. Q-объекты

from django.db.models import Q

# AND — книги-бестселлеры изданные после 2000
books = Book.objects.filter(
    Q(is_bestseller=True) & Q(published_date__gt="2000-01-01")
)

# OR — бестселлеры ИЛИ дешёвые книги
books = Book.objects.filter(
    Q(is_bestseller=True) | Q(price__lt=15)
)

# NOT — не бестселлеры
books = Book.objects.filter(~Q(is_bestseller=True))

# Комбинация
books = Book.objects.filter(
    (Q(is_bestseller=True) | Q(published_date__gt="2000-01-01"))
    & ~Q(author="George Orwell")
)

for book in books:
    print(book.title)

Пример 9. Обновление и удаление

# Обновление через объект
book = Book.objects.get(id=1)
book.price = 25
book.save()

# Массовое обновление через QuerySet
Book.objects.filter(is_bestseller=False).update(price=10)

# Удаление одной записи
book = Book.objects.get(id=2)
book.delete()

# Массовое удаление
Book.objects.filter(published_date__lt="1900-01-01").delete()