31
WEB-ПРОГРАММИРОВАНИЕ Лекция #7. Django ORM Яковенко К. С Омский государственный университет им. Ф. М. Достоевского Факультет компьютерных наук

Лекция #7. Django ORM

  • Upload
    -

  • View
    945

  • Download
    3

Embed Size (px)

Citation preview

Page 1: Лекция #7. Django ORM

WEB-ПРОГРАММИРОВАНИЕЛекция #7. Django ORM

Яковенко К. С

Омский государственный университет им. Ф. М. ДостоевскогоФакультет компьютерных наук

Page 2: Лекция #7. Django ORM

2

«Модель-Шаблон-Представление» (MTV)

«Модель» (M) — слой доступа к данным, знает о них всё: как получить доступ, как проверить, как с ними работать и как данные связаны между собой.

«Шаблон» (T) — слой представления данных, принимает решения относительно представления данных: как и что должно отображаться на странице или в другом типе документа.

«Представление» (V) — слой бизнес-логики, содержит логику получения доступа к моделям и применения соответствующих шаблонов. Можно рассматривать его как мост между моделями и шаблонами.

Page 3: Лекция #7. Django ORM

3

Определение моделей(Django ORM)

Object-Relational Mapping – объектно реляционное отображение

Преимущества ORM:

Инкапсуляция методов

Переносимость

Безопасность

Выразительность

Page 4: Лекция #7. Django 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()

Page 5: Лекция #7. Django ORM

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

);

Page 7: Лекция #7. Django ORM

7

Определение моделей.Универсальные параметры полей

Встроенные типы полей наследуются от django.db.models.Field и могут принимать следующие аргументы:

verbose_name – понятное человеку описание поля

primary_key – признак первичного ключа

unique – признак уникальности поля

blank – признак того, что поле может быть пустым

null – признак того, что поле может иметь значение NULL

default – значение поля по умолчанию

db_index – в б.д. создастся индекс для этого поля

и д.р.

Page 8: Лекция #7. Django ORM

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

Page 9: Лекция #7. Django ORM

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)

Page 10: Лекция #7. Django ORM

10

Получение объектов из базы данных

осуществляется с помощью классов:

Manager – это объект, с помощью которого Django выполняет запросы к базе данных.

По умолчанию класс Model имеет атрибут objects, который является экземпляром класса Manager.

QuerySet представляет набор объектов из базы данных удовлетворяющих заданным параметрам.

Page 11: Лекция #7. Django ORM

11

Выборка объектов в Django ORM

Методы класса Manager для получения данных:

all() – получает все объекты, возвращает QuerySet

filter(**kwargs) – задает критерий выбора, возвращает QuerySet

exclude(**kwargs) – выполняет действия обратные действиям метода filter

get(**kwargs) – получает единственную запись соответствующую критерию или возбуждает исключение.

и другие специфические методы.

Page 12: Лекция #7. Django ORM

12

Условия поиска по полюв методах filter, exclude, get и др.

Общий синтаксис передачи именованных аргументов: field__lookuptype=value, где lookuptype – дополнительный параметр поиска:

contains – поиск вхождении с учетом регистра

icontains – поиск вхождении без учета регистра

gt, gte, lt, lte – «больше», «больше или равно», «меньше», «меньше или равно»

in отбирает объекты из списка

isnull – эквивалентен операторам IS NULL и IS NOT NULL в SQL.

и другие

Page 13: Лекция #7. Django ORM

13

Объект QuerySet

«Cтроительные блоки» для создания и выполнения SQL-запросов, обладающие следующими свойствами:

обладает теми же методами, что и Manager

частично реализует интерфейс класса list

реализует ленивые вычисления для получения данных

кэширует полученные результаты

после каждого изменения, создается новый QuerySet

Page 14: Лекция #7. Django ORM

14

Дополнительные методы настройки фильтрации

order_by(*fields) – сортирует по нескольким полям'field' – по возрастанию '-field' – по убыванию

distinct([*fields]) – исключает повторяющиеся записи

count() – возвращает количество объектов

extra(select=None, where=None, params=None, tables=None, order_by=None, select_params=None) – позволяет создавать нестандартные запросы к БД.

и многие другие

Page 15: Лекция #7. Django ORM

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)# вернет один объект

Page 16: Лекция #7. Django ORM

16

Отношения между моделями«многие-к-одному»

реализуется за счет внешних ключейclass ForeignKey(othermodel[, **options])

class Relation(models.Model): field = models.ForeignKey(CustomModel) ...

Чтобы сослаться на модели, определенные в другом приложении:field = models.ForeignKey('app.CustomModel')

для создания рекурсивного отношения:field = models.ForeignKey('self')

Page 17: Лекция #7. Django ORM

17

Отношения между моделями «один-к-многим»

Если ForeignKey ссылается на модель, то любои объект этой модели будет иметь доступ к менеджеру RelatedManager, возвращающему экземпляры первои модели, связанные с данным объектом.

По умолчанию этот менеджер называется FOO_set, где FOO – имя модели-источника, записанное строчными буквами.

Имя FOO_set можно переопределить с помощью параметра related_name в определении поля типа ForeignKey.

Page 18: Лекция #7. Django ORM

18

Отношения между моделями«один-к-одному»

class OneToOneField(othermodel[, parent_link=False, **options])

field = models.OneToOneField(CustomModel)

аналогичен ForeignKey с атрибутом unique=True, но для организации обратной связи RelatedManager не создается, вместо него используется обычный атрибут.

parent_link флаг показывает, что при наследовании для обратнои ссылки на родительскии класс следует использовать данное поле.

Page 19: Лекция #7. Django ORM

19

Отношения между моделями«многие-к-многим»

class ManyToManyField(othermodel[, **options])

items = models.ManyToMany(CustomModel)

Django автоматически создает связующую таблицу для реализации отношения, но ее можно переопределить, указав в параметре through модель, соответствующую этои таблице.

Page 20: Лекция #7. Django ORM

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)

Page 21: Лекция #7. Django ORM

21

Метаданные модели

Общие настройки моделизадаются во вложенном классе Meta

class Book(models.Model):… class Meta: db_table = “Имя таблицы в базе данных” managed = True # Django создает таблицу в БД ordering = ['Сортировка по умолчанию'] unique_together = ('Набор имен полеи', 'значения

которых в совокупности должны быть уникальны',)…

Page 22: Лекция #7. Django ORM

22

Наследование моделей.Абстрактные базовые классы

class AbstractModel(models.Model):…class Meta:

abstract = True

Таблица для этой модели не создается!

Все поля модели копируются в таблицы дочерних классов

Класс Meta полностью наследуется за исключением параметра abstract

Page 23: Лекция #7. Django ORM

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)

Page 24: Лекция #7. Django ORM

24

Наследование моделей.Многотабличное наследование

выглядит как обычное наследование классов

наследует все атрибуты и методы родительского класса (за исключением класса Meta)

таблицы в базе данных создаются для каждой модели

связь между таблицами организуется с помощью полей типа ОпеToOneField

Page 25: Лекция #7. Django ORM

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

Page 26: Лекция #7. Django ORM

26

Активация моделей в проекте

В файле settings.py:

INSTALLED_APPS = ( # сообщает какие приложения в данном проекте # активированы

'django.contrib.auth',

'django.contrib.contenttypes',

'django.contrib.sessions',

'django.contrib.sites',

'app', # приложения пользователя

… # и сторонних разработчиков

)

Page 27: Лекция #7. Django ORM

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.

Page 28: Лекция #7. Django ORM

28

Создание и изменение базы данных

до django 1.7

manage.py validate # проверяет синтаксис и логику моделей

manage.py syncdb # создает еще не существующие таблицы, но не синхронизирует изменения в них

начиная с django 1.7

manage.py check # анализирует проект на наличие распространенных проблем

manage.py migrate [<app_label> [<migrationname>]] # синхронизирует состояние базы данных с помощью текущего набора моделей и миграций.

Page 29: Лекция #7. Django ORM

29

Создание и изменение базы данных

Миграции в Django используются для переноса изменений в моделях (добавления/удаления поля или модели и т.п.) на структуру базы данных.

Миграции – это очень мощный механизм, который нужно с осторожностью применять в реальных условиях.

manage.py makemigrations [<app_label>] # cоздает новые миграции на основе изменений, обнаруженных в модели.

До django 1.7 для миграций использовался пакет south

Page 30: Лекция #7. Django ORM

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

Page 31: Лекция #7. Django ORM

31

Яковенко Кирилл Сергеевич[email protected]

Омский государственный университет им. Ф. М. ДостоевскогоФакультет компьютерных наук