WEB-ПРОГРАММИРОВАНИЕ
Лекция #7. Django ORM
Яковенко К. С
Омский государственный университет им. Ф. М. Достоевского
Факультет компьютерных наук
2
«Модель-Шаблон-Представление» (MTV)
«Модель» (M) — слой доступа к данным, знает о них всё:
как получить доступ, как проверить, как с ними работать и
как данные связаны между собой.
«Шаблон» (T) — слой представления данных, принимает
решения относительно представления данных: как и что
должно отображаться на странице или в другом типе
документа.
«Представление» (V) — слой бизнес-логики, содержит
логику получения доступа к моделям и применения
соответствующих шаблонов. Можно рассматривать его как
мост между моделями и шаблонами.
3
Определение моделей
(Django ORM)
Object-Relational Mapping – объектно
реляционное отображение
Преимущества ORM:
Инкапсуляция методов
Переносимость
Безопасность
Выразительность
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
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
Определение моделей.
Типы полей
Часто употребляемые поля моделей:
Текстовые поля: CharField и TextField
Специфические поля:
EmailField, URLField и IPAddressField
Булевы поля: BooleanField и NullBooleanField
Поля для работы с файлами:
FilePathField, FileField и ImageField
Поля отношений:
ForeignKey, ManyToManyField, OneToOneField
7
Определение моделей.
Универсальные параметры полей
Встроенные типы полей наследуются от django.db.models.Field
и могут принимать следующие аргументы:
verbose_name – понятное человеку описание поля
primary_key– признак первичного ключа
unique – признак уникальности поля
blank – признак того, что поле может быть пустым
null – признак того, что поле может иметь значение NULL
default – значение поля по умолчанию
db_index – в б.д. создастся индекс для этого поля
и д.р.
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
Базовые операции над моделями 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
Получение объектов из базы данных
осуществляется с помощью классов:
Manager – это объект, с помощью которого Django
выполняет запросы к базе данных.
По умолчанию класс Model имеет атрибут objects, который
является экземпляром класса Manager.
QuerySet представляет набор объектов из базы данных
удовлетворяющих заданным параметрам.
11
Выборка объектов в Django ORM
Методы класса Manager для получения данных:
all() – получает все объекты, возвращает QuerySet
filter(**kwargs) – задает критерий выбора, возвращает
QuerySet
exclude(**kwargs) – выполняет действия обратные
действиям метода filter
get(**kwargs) – получает единственную запись
соответствующую критерию или возбуждает исключение.
и другие специфические методы.
12
Условия поиска по полю
в методах filter, exclude, get и др.
Общий синтаксис передачи именованных аргументов:
field__lookuptype=value, где lookuptype – дополнительный
параметр поиска:
contains – поиск вхождений с учетом регистра
icontains – поиск вхождений без учета регистра
gt, gte, lt, lte – «больше», «больше или равно»,
«меньше», «меньше или равно»
in отбирает объекты из списка
isnull – эквивалентен операторам IS NULL и IS NOT
NULL в SQL.
и другие
13
Объект QuerySet
«Cтроительные блоки» для создания и выполнения
SQL-запросов, обладающие следующими свойствами:
обладает теми же методами, что и Manager
частично реализует интерфейс класса list
реализует ленивые вычисления для получения
данных
кэширует полученные результаты
после каждого изменения, создается новый
QuerySet
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
Пример получения данных
>>> 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
Отношения между моделями
«многие-к-одному»
реализуется за счет внешних ключей
class ForeignKey(othermodel[, **options])
class Relation(models.Model):
field = models.ForeignKey(CustomModel)
...
Чтобы сослаться на модели, определенные в
другом приложении:
field = models.ForeignKey('app.CustomModel')
для создания рекурсивного отношения:
field = models.ForeignKey('self')
17
Отношения между моделями
«один-к-многим»
Если ForeignKey ссылается на модель, то любой
объект этой модели будет иметь доступ к менеджеру
RelatedManager, возвращающему экземпляры первой
модели, связанные с данным объектом.
По умолчанию этот менеджер называется FOO_set,
где FOO – имя модели-источника, записанное
строчными буквами.
Имя FOO_set можно переопределить с помощью
параметра related_name в определении поля типа
ForeignKey.
18
Отношения между моделями
«один-к-одному»
class OneToOneField(othermodel[, parent_link=False,
**options])
field = models.OneToOneField(CustomModel)
аналогичен ForeignKey с атрибутом unique=True, но
для организации обратной связи RelatedManager не
создается, вместо него используется обычный атрибут.
parent_link флаг показывает, что при наследовании для
обратной ссылки на родительский класс следует
использовать данное поле.
19
Отношения между моделями
«многие-к-многим»
class ManyToManyField(othermodel[, **options])
items = models.ManyToMany(CustomModel)
Django автоматически создает связующую
таблицу для реализации отношения, но ее
можно переопределить, указав в параметре
through модель, соответствующую этой
таблице.
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
Метаданные модели
Общие настройки модели
задаются во вложенном классе Meta
class Book(models.Model):
…
class Meta:
db_table = “Имя таблицы в базе данных”
managed = True # Django создает таблицу в БД
ordering = ['Сортировка по умолчанию']
unique_together = ('Набор имен полей','значения
которых в совокупности должны быть уникальны',)
…
22
Наследование моделей.
Абстрактные базовые классы
class AbstractModel(models.Model):
…
class Meta:
abstract = True
Таблица для этой модели не создается!
Все поля модели копируются в таблицы
дочерних классов
Класс Meta полностью наследуется за
исключением параметра abstract
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
Наследование моделей.
Многотабличное наследование
выглядит как обычное наследование классов
наследует все атрибуты и методы
родительского класса (за исключением
класса Meta)
таблицы в базе данных создаются для
каждой модели
связь между таблицами организуется с
помощью полей типа ОпеToOneField
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
Активация моделей в проекте
В файле settings.py:
INSTALLED_APPS = ( # сообщает какие приложения в данном проекте
# активированы
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'app', # приложения пользователя
… # и сторонних разработчиков
)
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
Создание и изменение базы данных
до django 1.7
manage.py validate # проверяет синтаксис и логику
моделей
manage.py syncdb # создает еще не существующие
таблицы, но не синхронизирует изменения в них
начиная с django 1.7
manage.py check # анализирует проект на наличие
распространенных проблем
manage.py migrate [<app_label> [<migrationname>]]
# синхронизирует состояние базы данных с помощью
текущего набора моделей и миграций.
29
Создание и изменение базы данных
Миграции в Django используются для переноса
изменений в моделях (добавления/удаления поля или
модели и т.п.) на структуру базы данных.
Миграции – это очень мощный механизм, который нужно
с осторожностью применять в реальных условиях.
manage.py makemigrations [<app_label>] # cоздает новые
миграции на основе изменений, обнаруженных в модели.
До django 1.7 для миграций использовался пакет south
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.")
31
Яковенко Кирилл Сергеевич
kirill.yakovenko@gmail.com
Омский государственный университет им. Ф. М. Достоевского
Факультет компьютерных наук

Лекция #7. Django ORM

  • 1.
    WEB-ПРОГРАММИРОВАНИЕ Лекция #7. DjangoORM Яковенко К. С Омский государственный университет им. Ф. М. Достоевского Факультет компьютерных наук
  • 2.
    2 «Модель-Шаблон-Представление» (MTV) «Модель» (M)— слой доступа к данным, знает о них всё: как получить доступ, как проверить, как с ними работать и как данные связаны между собой. «Шаблон» (T) — слой представления данных, принимает решения относительно представления данных: как и что должно отображаться на странице или в другом типе документа. «Представление» (V) — слой бизнес-логики, содержит логику получения доступа к моделям и применения соответствующих шаблонов. Можно рассматривать его как мост между моделями и шаблонами.
  • 3.
    3 Определение моделей (Django ORM) Object-RelationalMapping – объектно реляционное отображение Преимущества ORM: Инкапсуляция методов Переносимость Безопасность Выразительность
  • 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 Отношения между моделями «один-к-одному» classOneToOneField(othermodel[, parent_link=False, **options]) field = models.OneToOneField(CustomModel) аналогичен ForeignKey с атрибутом unique=True, но для организации обратной связи RelatedManager не создается, вместо него используется обычный атрибут. parent_link флаг показывает, что при наследовании для обратной ссылки на родительский класс следует использовать данное поле.
  • 19.
    19 Отношения между моделями «многие-к-многим» classManyToManyField(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: classBook(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.")
  • 31.
    31 Яковенко Кирилл Сергеевич kirill.yakovenko@gmail.com Омскийгосударственный университет им. Ф. М. Достоевского Факультет компьютерных наук