Содержание
Глава 3
Введение
В Главе 1 мы рассмотрели основы построения динамических веб-сайтов с помощью Django: настройка представлений и URLconfs
. Как мы поясняли, представления отвечают за обработку неких логических построений, и возвращают ответ в виде объекта HttpResponse
. В наших примерах этими логическими построениями было вычисление даты и времени.
В современных веб-приложениях подобные построения как правило включают в себя работу с базами данных. На фоне работы самого приложения, оно подключается к серверу базы данных, получает от него какие-то данные и отображает их на сайте. Сайт так же может предоставлять возможность посетителям наполнять эту базу данных какими-то данными.
Многие комплексные приложения являются комбинацией этих двух действий. Например, Amazon.com – прекрасный пример такого сайта. Каждая страница какого-то продукта по существу является результатом запроса к базе данных, отформатированного в HTML-формат, а когда посетитель добавляет свой обзор к товару – он выполняет добавление записи в базу данных обзоров товара.
Django отлично поддерживает создание веб-приложений, основанных на работе с базами данных, потому что в нём имеются простые но мощные инструменты для выполнения запросов к базам данных с использованием Python. В этой главе мы рассмотрим эту функциональность – уровень баз данных Django.
(Примечание: хотя требование знаний реляционных баз данных и SQL не является обязательным для использования баз данных с Django, но это крайне рекомендуется. Введение в их концепцию находится за пределами этой книги, однако продолжайте читать, даже если вы новичок в вопросах баз данных. Возможно, вам удастся понять некоторые основные идеи, исходя из контекста книги).
“Глупый” способ выполнения запросов к базе данных из представлений
В Главе 1 мы показывали “глупый” способ использования представлений для вывода данных (вписывая тест прямо в представление), а вот сходный метод получения данных из базы данных в представление. Очень просто: используя любую библиотеку Python для выполнения SQL-запросов – получаем данные в представление.
В следующем примере мы используем библиотеку MySQLdb
что бы подключиться к базе, несколько секунд потратить на извлечение данных, и передать их в представление, что бы отобразить на веб-странице:
from django.shortcuts import render import MySQLdb def book_list(request): db = MySQLdb.connect(user='me', db='mydb', passwd='secret', host='localhost') cursor = db.cursor() cursor.execute('SELECT name FROM books ORDER BY name') names = [row[0] for row in cursor.fetchall()] db.close() return render(request, 'book_list.html', {'names': names})
Это способ будет работать, но вы сразу же столкнётесь с некоторыми проблемами:
- Мы записываем параметры подключения прямо в представление. Было бы лучше, если бы они хранились где-то в настройках Django.
- Нам приходится писать много шаблонного кода: создание подключения, создание курсора, выполнение выражения, закрытие подключения. Было бы лучше, если бы мы могли просто сказать – какой результат мы хотим получить.
- Мы привязаны к MySQL. Если в дальнейшем мы решим перейти на использование PostgreSQL – нам придётся использовать новый драйвер (например –
psycopg
вместоMySQLdb
), менять параметры подключения, и – в зависимости от самого запроса – возможно переписывать весь SQL-запрос. Было бы лучше, сервер баз данных должен быть некоей абстрактной сущностью, что бы изменение сервера можно было сделать в одном месте (это особенно важно, если вы создаёте open-source приложение, и хотите что бы им пользовалось много людей).
Как вы догадываетесь, система уровня баз данных в Django решает эти проблемы. Вот наглядный пример того, как мы могли бы изменить предыдущий пример с использованием API баз данных в Django:
from django.shortcuts import render from mysite.books.models import Book def book_list(request): books = Book.objects.order_by('name') return render(request, 'book_list.html', {'books': books})
Мы объясним далее – что здесь чем занимается, пока просто посмотрите – как это выглядит.
Продолжение – Django Book: концепция разработки MVC – Model, View, Controller.