Web-программирование
Лекция #7. Django ORM
Цикл лекций читается в Омском государственном университете им. Ф.М.Достоевского на факультете компьютерных наук.
Лектор: Яковенко Кирилл Сергеевич.
2. 2
«Модель-Шаблон-Представление» (MTV)
«Модель» (M) — слой доступа к данным, знает о них всё:
как получить доступ, как проверить, как с ними работать и
как данные связаны между собой.
«Шаблон» (T) — слой представления данных, принимает
решения относительно представления данных: как и что
должно отображаться на странице или в другом типе
документа.
«Представление» (V) — слой бизнес-логики, содержит
логику получения доступа к моделям и применения
соответствующих шаблонов. Можно рассматривать его как
мост между моделями и шаблонами.
4. 4
Модель данных в Django
Логическое описание структуры данных, хранящихся в БД,
представленное на языке Python.
Все модели представляют из себя класс,
наследующий — django.db.models.Model
# app/models.py (общий синтаксис):
from django.db import models
class CustomModel(models.Model):
name = models.CharField(max_length=30)
body = models.TextField()
email = models.EmailField(blank=True)
number = models.IntegerField()
5. 5
SQL эквивалент модели Django
Модель Django можно рассматривать как
SQL-команду «CREATE TABLE»
CREATE TABLE “app_custommodel” (
“id” serial NOT NULL PRIMARY KEY,
“name” varchar(30) NOT NULL,
“body” text NOT NULL,
“email” varchar(75) NOT NULL,
“number” integer NOT NULL
);
6. 6
Определение моделей.
Типы полей
Часто употребляемые поля моделей:
Текстовые поля: CharField и TextField
Специфические поля:
EmailField, URLField и IPAddressField
Булевы поля: BooleanField и NullBooleanField
Поля для работы с файлами:
FilePathField, FileField и ImageField
Поля отношений:
ForeignKey, ManyToManyField, OneToOneField
7. 7
Определение моделей.
Универсальные параметры полей
Встроенные типы полей наследуются от django.db.models.Field
и могут принимать следующие аргументы:
verbose_name – понятное человеку описание поля
primary_key– признак первичного ключа
unique – признак уникальности поля
blank – признак того, что поле может быть пустым
null – признак того, что поле может иметь значение NULL
default – значение поля по умолчанию
db_index – в б.д. создастся индекс для этого поля
и д.р.
8. 8
Базовые операции над моделями Django
Создание экземпляра модели:
class Model(**kwargs), где kwargs – именованные
аргументы, задающие поля модели и их значения.
Сохранение/обновление данных в базе данных:
Model.save([force_insert=False, force_update=False,
using=DEFAULT_DB_ALIAS, update_fields=None])
Удаление объекта из базы данных:
Model.delete([using=DEFAULT_DB_ALIAS])
9. 9
Базовые операции над моделями Django
>>> p = CustomModel(name=’Name’, body='...', number=0)
>>> p.id # None
>>> p.save() # вставка данных
>>> p.id # 52
# INSERT INTO “apps_custommodel” (“name”,“body”,“email”,“number”)
VALUES ('Name','…','', 0) RETURNING “app_custommodel”.”id”
>>> p.name = 'Another one name'
>>> p.save(update_fields=['name']) # обновление данных
# UPDATE “app_custommodel” SET “name” = “Another one name” WHERE
“app_custommodel”.”id” = 52
>>> p.delete() # удаление объекта
# DELETE FROM “app_custommodel” WHERE “app_custommodel”.”id” IN (52)
10. 10
Получение объектов из базы данных
осуществляется с помощью классов:
Manager – это объект, с помощью которого Django
выполняет запросы к базе данных.
По умолчанию класс Model имеет атрибут objects, который
является экземпляром класса Manager.
QuerySet представляет набор объектов из базы данных
удовлетворяющих заданным параметрам.
11. 11
Выборка объектов в Django ORM
Методы класса Manager для получения данных:
all() – получает все объекты, возвращает QuerySet
filter(**kwargs) – задает критерий выбора, возвращает
QuerySet
exclude(**kwargs) – выполняет действия обратные
действиям метода filter
get(**kwargs) – получает единственную запись
соответствующую критерию или возбуждает исключение.
и другие специфические методы.
12. 12
Условия поиска по полю
в методах filter, exclude, get и др.
Общий синтаксис передачи именованных аргументов:
field__lookuptype=value, где lookuptype – дополнительный
параметр поиска:
contains – поиск вхождений с учетом регистра
icontains – поиск вхождений без учета регистра
gt, gte, lt, lte – «больше», «больше или равно»,
«меньше», «меньше или равно»
in отбирает объекты из списка
isnull – эквивалентен операторам IS NULL и IS NOT
NULL в SQL.
и другие
13. 13
Объект QuerySet
«Cтроительные блоки» для создания и выполнения
SQL-запросов, обладающие следующими свойствами:
обладает теми же методами, что и Manager
частично реализует интерфейс класса list
реализует ленивые вычисления для получения
данных
кэширует полученные результаты
после каждого изменения, создается новый
QuerySet
14. 14
Дополнительные методы настройки
фильтрации
order_by(*fields) – сортирует по нескольким полям
'field'– по возрастанию '-field'– по убыванию
distinct([*fields]) – исключает повторяющиеся
записи
count() – возвращает количество объектов
extra(select=None, where=None, params=None,
tables=None, order_by=None, select_params=None) –
позволяет создавать нестандартные запросы к БД.
и многие другие
15. 15
Пример получения данных
>>> CustomModel.object.get(pk=1)
# исключение CustomModel.DoesNotExist
>>> CustomModel.objects.create(name='Name1', body='...', number=0)
>>> CustomModel.objects.create(name='Name2', body='...', number=1)
>>> CustomModel.objects.get(name__icontains='name')
# исключение CustomModel.MultipleObjectsReturned
>>> CustomModel.objects.count()
1
>>> CustomModel.objects.filter(name__icontains='name')
# вернет два объекта
>>> CustomModel.objects.filter(name__icontains='name').order_by(“-number”)
# сначала вернет объект “Name2”, а затем “Name1”
>>> CustomModel.objects.filter(name__icontains='name', number=0)
# вернет один объект
>>> CustomModel.objects.filter(name__icontains='name').exclude(number=0)
# вернет один объект
16. 16
Отношения между моделями
«многие-к-одному»
реализуется за счет внешних ключей
class ForeignKey(othermodel[, **options])
class Relation(models.Model):
field = models.ForeignKey(CustomModel)
...
Чтобы сослаться на модели, определенные в
другом приложении:
field = models.ForeignKey('app.CustomModel')
для создания рекурсивного отношения:
field = models.ForeignKey('self')
17. 17
Отношения между моделями
«один-к-многим»
Если ForeignKey ссылается на модель, то любой
объект этой модели будет иметь доступ к менеджеру
RelatedManager, возвращающему экземпляры первой
модели, связанные с данным объектом.
По умолчанию этот менеджер называется FOO_set,
где FOO – имя модели-источника, записанное
строчными буквами.
Имя FOO_set можно переопределить с помощью
параметра related_name в определении поля типа
ForeignKey.
18. 18
Отношения между моделями
«один-к-одному»
class OneToOneField(othermodel[, parent_link=False,
**options])
field = models.OneToOneField(CustomModel)
аналогичен ForeignKey с атрибутом unique=True, но
для организации обратной связи RelatedManager не
создается, вместо него используется обычный атрибут.
parent_link флаг показывает, что при наследовании для
обратной ссылки на родительский класс следует
использовать данное поле.
19. 19
Отношения между моделями
«многие-к-многим»
class ManyToManyField(othermodel[, **options])
items = models.ManyToMany(CustomModel)
Django автоматически создает связующую
таблицу для реализации отношения, но ее
можно переопределить, указав в параметре
through модель, соответствующую этой
таблице.
20. 20
Пример организации отношений
между моделями
class Author(models.Model):
name = models.CharField(max_length=100)
class Book(models.Model):
title = models.CharField(max_length=100)
authors = models.ManyToManyField(Author,
through=”Authoring”)
class Authoring(models.Model):
collaboration_type = models.CharField(max_length=100)
book = models.ForeignKey(Book)
author = models.ForeignKey(Author)
21. 21
Метаданные модели
Общие настройки модели
задаются во вложенном классе Meta
class Book(models.Model):
…
class Meta:
db_table = “Имя таблицы в базе данных”
managed = True # Django создает таблицу в БД
ordering = ['Сортировка по умолчанию']
unique_together = ('Набор имен полей','значения
которых в совокупности должны быть уникальны',)
…
22. 22
Наследование моделей.
Абстрактные базовые классы
class AbstractModel(models.Model):
…
class Meta:
abstract = True
Таблица для этой модели не создается!
Все поля модели копируются в таблицы
дочерних классов
Класс Meta полностью наследуется за
исключением параметра abstract
23. 23
Абстрактные базовые классы (пример)
Python:
class Book(models.Model):
name = models.CharField(max_length=100)
class Meta:
abstract = True
class ScienceBook(Book):
pass
class FantasticBook(Book):
pass
SQL:
CREATE TABLE "app_sciencebook" (
"id" integer NOT NULL PRIMARY KEY,
"name" varchar(100) NOT NULL
)
CREATE TABLE "app_fantasticbook" (
"id" integer NOT NULL PRIMARY KEY,
"name" varchar(100) NOT NULL
)
24. 24
Наследование моделей.
Многотабличное наследование
выглядит как обычное наследование классов
наследует все атрибуты и методы
родительского класса (за исключением
класса Meta)
таблицы в базе данных создаются для
каждой модели
связь между таблицами организуется с
помощью полей типа ОпеToOneField
25. 25
Многотабличное наследование (пример)
Python:
class Book(model.Model):
name = models.CharField(
max_length=100
)
class ScienceBook(Book):
pass
class FantasticBook(Book):
pass
SQL:
CREATE TABLE "t_book" (
"id" integer NOT NULL PRIMARY KEY,
"name" varchar(100) NOT NULL
)
CREATE TABLE "t_sciencebook" (
"book_ptr_id" integer NOT NULL
PRIMARY KEY REFERENCES "t_book" ("id")
)
CREATE TABLE "t_fantasticbook" (
"book_ptr_id" integer NOT NULL
PRIMARY KEY REFERENCES "t_book" ("id")
)
26. 26
Активация моделей в проекте
В файле settings.py:
INSTALLED_APPS = ( # сообщает какие приложения в данном проекте
# активированы
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'app', # приложения пользователя
… # и сторонних разработчиков
)
27. 27
Настройка подключения к базе данных
settings.py:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'mydatabase',
'USER': 'mydatabaseuser',
'PASSWORD': 'mypassword',
'HOST': '127.0.0.1',
'PORT': '5432',
}
}
Начиная с django 1.6 база данных по умолчанию конфигурируется в sqlite3.
28. 28
Создание и изменение базы данных
до django 1.7
manage.py validate # проверяет синтаксис и логику
моделей
manage.py syncdb # создает еще не существующие
таблицы, но не синхронизирует изменения в них
начиная с django 1.7
manage.py check # анализирует проект на наличие
распространенных проблем
manage.py migrate [<app_label> [<migrationname>]]
# синхронизирует состояние базы данных с помощью
текущего набора моделей и миграций.
29. 29
Создание и изменение базы данных
Миграции в Django используются для переноса
изменений в моделях (добавления/удаления поля или
модели и т.п.) на структуру базы данных.
Миграции – это очень мощный механизм, который нужно
с осторожностью применять в реальных условиях.
manage.py makemigrations [<app_label>] # cоздает новые
миграции на основе изменений, обнаруженных в модели.
До django 1.7 для миграций использовался пакет south
30. 30
Вспомогательные функции в
представлениях
Для автоматизации рутинных действий – django.shortcuts
Применительно к моделям чаще всего используются:
get_object_or_404(klass,*args, **kwargs)
Try:
my_object = Book.objects.get(pk=1)
except MyModel.DoesNotExist:
raise Http404("No Book matches the given query.")
get_list_or_404(klass,*args,**kwargs)
books = list(Book.objects.filter(name__startswith='Will'))
if not books:
raise Http404("No Book matches the given query.")