Django ORM – встроенная ORM Django

онлайн тренер по питону
Онлайн-тренажер Python 3 для начинающих

Теория без воды. Задачи с автоматической проверкой. Подсказки на русском языке. Работает в любом современном браузере.

начать бесплатно

Введение

При разработке веб-приложений на Python одним из наиболее популярных фреймворков является Django. Одной из ключевых особенностей Django является его встроенная система объектно-реляционного отображения (ORM), которая позволяет разработчикам взаимодействовать с базами данных, используя высокоуровневые методы Python вместо написания сырых SQL-запросов. Это упрощает процесс разработки и делает код более читаемым и поддерживаемым.

Что такое ORM и как работает Django ORM

Принципы объектно-реляционного отображения

Объектно-реляционное отображение (ORM) — это технология, которая связывает базы данных с концепциями объектно-ориентированных языков программирования, таких как Python. ORM позволяет разработчикам работать с базой данных, используя объекты, классы и методы, что делает взаимодействие с данными более интуитивным и естественным.

Django ORM как связующее звено между Python и SQL

Django ORM автоматически преобразует запросы, написанные на Python, в соответствующие SQL-запросы, выполняемые в базе данных. Это позволяет разработчикам сосредоточиться на логике приложения, не беспокоясь о деталях взаимодействия с базой данных.

Основные компоненты Django ORM

  • Модели (Models): Определяют структуру данных в виде классов Python, где каждый класс соответствует таблице в базе данных.

  • Менеджеры (Managers): Предоставляют интерфейс для выполнения запросов к базе данных через методы модели.

  • Запросы (QuerySets): Представляют собой наборы данных, полученных из базы, и поддерживают фильтрацию, сортировку и другие операции.

Установка и настройка

Для начала работы с Django ORM необходимо установить Django и создать новый проект:

bash
pip install django django-admin startproject myproject cd myproject

После этого создайте приложение внутри проекта:

bash
python manage.py startapp myapp

Добавьте созданное приложение в файл settings.py:

python
INSTALLED_APPS = [ # ... 'myapp', ]

Создание моделей данных

В файле models.py вашего приложения определите модели:

python
from django.db import models class Author(models.Model): name = models.CharField(max_length=100) birth_date = models.DateField() class Book(models.Model): title = models.CharField(max_length=200) author = models.ForeignKey(Author, on_delete=models.CASCADE) published_date = models.DateField()

После определения моделей выполните миграции для создания соответствующих таблиц в базе данных:

bash
python manage.py makemigrations python manage.py migrate

Создание и выполнение запросов

Django ORM позволяет легко выполнять операции создания, чтения, обновления и удаления (CRUD):

  • Создание записи:

python
author = Author.objects.create(name='Лев Толстой', birth_date='1828-09-09')
  • Чтение записей:

python
authors = Author.objects.all() tolstoy = Author.objects.get(name='Лев Толстой')
  • Обновление записи:

python
tolstoy.birth_date = '1828-09-09' tolstoy.save()
  • Удаление записи:

python
tolstoy.delete()

Связи между моделями

Django ORM поддерживает различные типы связей между моделями:

  • One-to-Many: Используется ForeignKey, как в примере выше с моделями Author и Book.

  • Many-to-Many: Используется ManyToManyField:

python
class Reader(models.Model): name = models.CharField(max_length=100) books = models.ManyToManyField(Book)
  • One-to-One: Используется OneToOneField:

python
class Profile(models.Model): user = models.OneToOneField(User, on_delete=models.CASCADE) bio = models.TextField()

Оптимизация запросов и производительность

Для повышения производительности запросов в Django ORM рекомендуется использовать методы select_related и prefetch_related для предзагрузки связанных объектов и уменьшения количества запросов к базе данных.

python
# Предзагрузка связанных объектов с помощью select_related books = Book.objects.select_related('author').all() # Предзагрузка связанных объектов с помощью prefetch_related authors = Author.objects.prefetch_related('book_set').all()

Тестирование и отладка

Django предоставляет встроенные инструменты для тестирования приложений, включая тестирование моделей и запросов ORM. Рекомендуется использовать модуль unittest или pytest для написания тестов и обеспечения надежности кода.

Расширенные возможности Django ORM

  • Агрегации и аннотации: Позволяют выполнять вычисления, такие как подсчет, сумма, среднее значение и т.д., непосредственно в запросах.

python
from django.db.models import Count author_books = Author.objects.annotate(num_books=Count('book'))
  • Сырые SQL-запросы: В случаях, когда требуется выполнить специфический SQL-запрос, можно использовать метод raw:

python
results = Author.objects.raw('SELECT * FROM myapp_author')

Сравнение с другими ORM

Характеристика Django ORM SQLAlchemy Peewee
Простота использования Высокая Средняя Высокая
Гибкость Средняя Высокая Средняя
Производительность Высокая Высокая Средняя
Сообщество и поддержка Широкое Широкое Ограниченное

Полный справочник по работе с Django ORM

Определение моделей

python
from django.db import models class Author(models.Model): name = models.CharField(max_length=100) age = models.IntegerField() class Book(models.Model): title = models.CharField(max_length=200) author = models.ForeignKey(Author, on_delete=models.CASCADE) published = models.DateField() rating = models.FloatField(null=True, blank=True)

Типы полей

Поле Назначение
CharField(max_length) Строка ограниченной длины.
TextField() Длинный текст.
IntegerField() Целое число.
FloatField() Число с плавающей точкой.
BooleanField() Логическое значение.
DateField() / DateTimeField() Дата / дата и время.
EmailField() Email-адрес.
ForeignKey(...) Связь "многие к одному".
ManyToManyField(...) Множественная связь.
OneToOneField(...) Связь "один к одному".
FileField() / ImageField() Работа с файлами.

Создание и сохранение объектов

python
author = Author(name="Лев Толстой", age=82) author.save() book = Book.objects.create(title="Война и мир", author=author, published="1869-01-01")

Получение объектов

Метод Описание
Book.objects.all() Все записи.
Book.objects.filter(title__icontains="мир") Фильтрация.
Book.objects.get(id=1) Один объект (ошибка, если не найден или больше одного).
Book.objects.first() / .last() Первый / последний объект.
Book.objects.exclude(rating=None) Исключение по условию.
Book.objects.count() Количество записей.

Поиск по связям

python
# Все книги автора books = Book.objects.filter(author__name="Лев Толстой") # Автор книги book = Book.objects.get(title="Война и мир") author = book.author

Обновление объектов

python
book = Book.objects.get(id=1) book.title = "Анна Каренина" book.save()

Массовое обновление:

python
Book.objects.filter(rating__isnull=True).update(rating=0)

Удаление объектов

python
book = Book.objects.get(id=1) book.delete() Book.objects.filter(rating=0).delete()

Работа с Q и F

python
from django.db.models import Q, F # Сложные фильтры Book.objects.filter(Q(title__icontains="мир") | Q(title__icontains="Анна")) # Сравнение полей Book.objects.filter(rating__gt=F('author__age'))

Сортировка

python
Book.objects.order_by('title') # По возрастанию Book.objects.order_by('-published') # По убыванию

Агрегация и аннотация

python
from django.db.models import Count, Avg # Агрегация Book.objects.aggregate(Avg('rating')) # Аннотация к каждому автору Author.objects.annotate(book_count=Count('book'))

Работа с связанными объектами

Операция Пример
Получить все книги автора author.book_set.all()
Добавить книгу автору author.book_set.create(title="Новая книга")

Many-to-Many

python
class Tag(models.Model): name = models.CharField(max_length=50) class Post(models.Model): title = models.CharField(max_length=100) tags = models.ManyToManyField(Tag)

Работа с такими связями:

python
post = Post.objects.get(id=1) tag = Tag.objects.get(name="django") post.tags.add(tag) post.tags.remove(tag) post.tags.clear()

Миграции базы данных

bash
python manage.py makemigrations python manage.py migrate

Менеджеры и QuerySet

Создание пользовательского менеджера:

python
class PublishedManager(models.Manager): def get_queryset(self): return super().get_queryset().filter(published__isnull=False) class Book(models.Model): ... objects = models.Manager() published_books = PublishedManager()

Raw SQL и extra()

python
Book.objects.raw("SELECT * FROM myapp_book WHERE rating > %s", [3.5])

Когда использовать Django ORM

  • Когда нужно работать с БД декларативно.

  • Когда нужна связь между таблицами через классы.

  • Для админки, API, форм, валидации, связанных с данными.

  • Когда важна поддержка различных СУБД (PostgreSQL, SQLite, MySQL).