Цель лекции: Рассмотреть основную терминологию Django; создать основную страницу приложения; создать структуру шаблона проекта на Django; настроить основной загрузчик для приложения, создать шаблон основной страницы.
Ключевые термины: django, bootstrap, файл, html, проект, css, class, python, user, admin, модель, страница, представление, приложение, пользователь
Django – это фреймворк, построенный на технологии MVC. На протяжении всего кода контроллер называется представлением, а представление называется шаблоном. Представление в Django – это компонент, который получает и манипулирует данными, а шаблон – это компонент, представляющий данные пользователю. По этой причине Django называют Модель-Шаблон-Представление (MTV) фреймворк. Эта разница не отменяет того факта, что Django является MVC фреймворком, не влияет на разработку приложений, но для предотвращения возможных коллизий требуется держать эту терминологию в голове, если вы соберетесь использовать MVC фреймворк.
Вы думаете, что эта глава – глубокое погружение в основные компоненты Django. Вы узнаете, как создавать динамические страницы, с помощью представлений, как хранить и управлять данными в базе данных с помощью моделей и как упростить генерацию страниц, с помощью шаблонов.
В процессе изучения этих особенностей, вы сформируете фундаментальную идею о том, как работают компоненты Django и взаимодействуют друг с другом. В более поздних главах, мы изучим эти компоненты более глубоко, когда разработаем больше возможностей и добавим их в приложение.
Наш проект собирается быть микроблогинговым сайтом, где у каждого пользователя будет общедоступная страница, на которой разместятся твиты в хронологическом порядке.
Первое, что приходит в голову при виде начальной страницы сервера разработки – это вопрос, как можно изменить ее. Чтобы создать собственную начальную страницу, нам нужно определить точку входа для нашего приложения в форме URL-адреса и указать Django вызвать особую функцию Python, когда посетитель обращается к данному URL. Мы напишем эту функцию Python сами и отобразим наше собственное приветственное сообщение.
В этом разделе в основном повторение конфигурации, сделанной в предыдущей главе, но наша цель здесь – собрать все инструкции вместе здесь, так что начальная загрузка проекта займет меньше страниц.
Мы настроим виртуальное окружение на правильную работу Django, используя следующую команду:
virtualenv djangoenv
Вы получите следующий вывод:
Using base prefix 'c:\\python34' New python executable in djangoenv\Scripts\python.exe Installing setuptools, pip, wheel...done.
Теперь нам нужно активировать виртуальное окружение и настроить все переменные среды таким образом, чтобы всё установленное Python будет перенаправляться в это окружение, не затрагивая другие параметры:
djangoenv\Scripts\activate
Вывод может быть следующим:
(djangoenv) C:\new1>
Хотя мы уже и устанавливали Django, мы сделаем это снова, потому что Django управляется virtualenv, которая не может разрешить работать другим пользователям или проектам (или себе самому) работать поверх него.
pip install django
Вы можете получить следующую ошибку:
bad interpreter: No such file or directory
Если такая ошибка получена, то создаем виртуальное окружение внутри пути без пробелов. Это быть потому, что в пути к расположению, где вы создали свое виртуальное окружение, существует каталог, чье имя содержит пробел, например,
/home/sergio/folder name with space$virtualenv djangoenv.
Если это так, то измените имя каталогу на что-то похожее на это:
/home/sergio/folder_name_with_no_space$virtualenv djangoenv
Теперь мы можем продолжить установку Django, используя команду pip install django. Вывод может выглядеть следующим образом:
Collecting django Using cached Django-1.8.4-py2.py3-none-any.whl Installing collected packages: django Successfully installed django-1.8.4
Теперь прежде чем мы перейдем к созданию нашего приложения Django, мы убедимся, что установили Git. Чтобы узнать установленную версию Git, используйте следующую команду:
git --version
Вывод может быть следующим:
git version 1.9.1
Это подтверждает, что мы установили Git. Конечно же, вы можете спросить, будем ли мы использовать систему контроля версий для этого проекта, и наш ответ: Да. По мере продвижения вперед, мы будем использовать систему контроля версий для большинства файлов проекта.
В этом разделе мы создадим структуру для нашего проекта, к примеру, создадим каталог для нашего проекта с названием mytweets, установим необходимый пакет для нашего проекта и т.д. Выполним следующую команду:
django-admin.py startproject mytweets
Эта команда создаст каталог под названием mytweets, который мы будем использовать в качестве каталога нашего проекта. В текущем каталоге мы увидим два вложенных каталога: environment и mytweets. Вопрос заключается в том, собираемся ли мы включить эти два каталога в систему контроля версий? Мы не будем этого делать, потому что эти файлы являются весьма специфическими для вашей текущей системы. Они никак не помогут настроить такое же окружение, как наше. Кроме этого, есть и другой способ сделать это в Python: с помощью команды pip freeze. Эта команда делает моментальный снимок всех текущих библиотек, установленных в приложении Django, и вы можете их список в текстовый файл и использовать в системе контроля версий. Таким образом, ваш юный разработчик может скачать ту же версию библиотек. Не правда ли, путь Python решает?
Самый распространенный метод для установки новых пакетов – использование команды pip. Есть три версии команды pip install, и они представлены ниже:
pip install PackageName
Это команда по умолчанию и устанавливает последнюю версию пакета
pip install PackageName==l.0.4
Используя параметр ==, можно установвить конкретную версию пакета. В данном случае, это версия 1.0.4.
pip install 'PackageName>=1.0.41 # minimum version
Используйте эту команду, когда вы не уверены в устанавливаемой версии пакета, которую хотите установить, но помните о том, что вам нужна минимальная версия библиотеки.
Легко использовать команду pip для установки библиотек. Вы можете это сделать, использовав следующую команду:
pip install -r requirements.txt
Теперь необходимо "заморозить" библиотеки:
pip freeze > requirements.txt
Это "замораживает" библиотеки, установленные для проекта с номером версии, и сохраняет их в файл с именем requirements.txt.
На этой стадии нашего проекта действие команды freeze выглядит примерно так:
Django==l.6.5 argparse==l.2.1 wsgiref == 0.1.2
Для обратной установки этих библиотек в ваше только что созданное окружение с проектом, мы можем запустить следующую команду:
pip install -r requirements.txt
Теперь мы можем приступить к инициализации нашей директории с кодом в виде репозитория Git и изменить текущий путь на $cd mytweets. Выполните следующую команду для построения репозитория Git в каталоге вашего проекта:
git init
Результат будет следующим:
Initialized empty Git repository in C:\new1\mytweets\.git\
Если мы запустим все команды на системе, основанной на Linux для подробного вывода списка каталога мы увидим следующий вывод:
drwxrwxr-x 7 sergio sergio 4096 Aug 2 16:07 .git/
Это каталог .git, который, согласно соглашению об именах(начинается с точки) скрыт от обычного просмотра каталога, то есть, это каталог, где помещаются все связанные с Git файлы, такие как ветви, файлы, добавленные в промежуточную область, логи, и сохраняются. Удаление этого конкретного каталога сделает ваш каталог Git-свободным (свободным от контроля версий) и он становится таким же обычным каталогом, как любой другой каталог в вашей текущей системе.
Мы можем добавить все наши текущие файлы в каталог промежуточной области, используя следующую команду:
$git add .
Используйте следующую команду, для первого подтверждения проекта:
git commit -m "Начальная промежуточная версия проекта."
Вывод может быть следующим:
[master (root-commit) 00f3f54] Первоначальная промежуточная версия проекта warning: LF will be replaced by CRLF in manage.py. The file will have its original line endings in your working directory. warning: LF will be replaced by CRLF in mytweets/settings.py. The file will have its original line endings in your working directory. warning: LF will be replaced by CRLF in mytweets/urls.py. The file will have its original line endings in your working directory. warning: LF will be replaced by CRLF in mytweets/wsgi.py. The file will have its original line endings in your working directory. 5 files changed, 149 insertions(+) create mode 100644 manage.py create mode 100644 mytweets/__init__.py create mode 100644 mytweets/settings.py create mode 100644 mytweets/urls.py create mode 100644 mytweets/wsgi.py C:\new1\mytweets>
Первая строка (здесь это master) говорит о том, что мы в ветке master, а другие строки о том. какие файлы попали в промежуточную область.
Итак, мы настроили основной шаблон Django и добавили его в систему контроля версий. то же может быть проверено с помощью следующей команды:
git log
Вывод может быть следующим:
commit 00f3f542089ffbaaf88df3e085fbdba10c1a3525 Author: ratan <tilllindemann85@outlook.com> Date: Tue Sep 1 18:32:22 2015 +0300 Первоначальная промежуточная версия проекта
Инструкции по настройке автора и генерации SSH-ключей для выгрузки на удаленный репозиторий могут быть найдены по следующим ссылкам:
https://help.github.com/articles/set-up-git https://help.github.com/artides/generating-ssh-keys
Как говорилось в предыдущей главе, bootstrap –основной фреймворк для дизайна пользовательского интерфейса. Мы предполагаем, что действовать будем вторым способом, а именно, скачиванием вручную файлов bootstrap и связывание их в каталог static.
Этот метод подразумевает, что мы не будем выполнять следующую команду:
pip install django-bootstrap3
Детализированная документация по этому внедрению может быть найдена на: http://django-bootstrap3.readthedocs.org/
Мы используем тот метод, который предполагает скачать файлы boostrap и распаковать их в каталог static нашего проекта.
Для начала мы должны скачать статические файлы boostrap по следующему официальному веб-адреса:
Перейдя по этой ссылке, вы найдете кнопку "Скачать". Нажав эту кнопку, нажмите на "Скачать Bootstrap". Это закачает на ваш компьютер файлы Bootstrap в формате zip. Вы скачаете файл с названием типа bootstrap-3.2.O-dist.zip. Распакуйте содержимое этого файла. После распаковки будет создана следующая структура в каталоге bootstrap- 3.2.O-dist:
I-- css |-- bootstrap.css |--bootstrap.css.map |--bootstrap.min.css |-- bootstrap-theme.css |-- bootstrap-theme.css.map |-- bootstrap-theme.min.css |-- fonts I *" glyphicons-halflings-regular.eot Iglyphicons-halflings-regular.svg I~~ glyphicons-halflings-regular.ttf Iglyphicons-halflings-regular.woff I-- js |-- bootstrap.js |-- boot strap.min.js
Особые для приложения статические файлы будут находиться в подкаталоге static внутри приложения. Django просматривает эти подкаталоги, исходя из настройки STATICFILES_DIRS.
Давайте обновим эти настройки для определения поддиректории статических файлов в файле settings.py.
Мы обновим файл нашего проекта settings.py, как принято использовать его с Twitter Bootstrap:
STATICFILES_DIRS = ( os.path.join( os.path.dirname( __files__ ), 'static' ), )
Теперь, переменная static будет папкой, в которой мы будем хранить файлы Bootstrap. Мы создадим папку static внутри наш каталога текущего проекта и скопируем все распакованные файлы bootstrap в эту папку.
Для целей разработки мы будем держать большую часть параметров, как эти, например, по умолчанию в базе данных SQLite; позже мы можем изменить это во время развертывания нашего тестового приложения на MySQL или любую другую базу данных по выбору.
Теперь прежде чем мы будем использовать bootstrap в наших проектах, есть некоторые основополагающие концепции, которые мы должны знать, чтобы понять bootstrap как фронтэнд фреймворк.
Bootstrap создает дизайн страниц, основанный на системе сетки, и есть три основных элемента сетки, а именно:
Контейнер также обеспечивает заполнение содержимого из углов браузера что они не касаются боковой стороны области просмотра. По умолчанию заполнение — 15 px. Вам никогда не нужен другой контейнер внутри контейнера. На следующем рисунке показана структура контейнера:
Строки имеют 15 px отрицательный отступ с каждой стороны, которая выталкивает их на верхнюю часть отступа в 15 px контейнера от границы. В результате они становятся отрицательными, и строка касается края контейнера, отрицательный отступ от стороны накладывается на отступ от границы. Таким образом строка не выталкивается отступом контейнера от границы. Никогда не используйте строку за пределами контейнера.
Столбцы снова имеют отступ от стороны 15 px, поэтому содержимое столбцов помещается на расстоянии 15 px от края области видимости контейнера.
Таким образом нам не нужен специальный отступ слева и справа для первого и последнего столбца. Теперь обеспечивается равномерный зазор в 15 px по всем столбцам.
Содержимое внутри столбца выталкивается в месторасположение столбцов, и они разделяются зазором в 30 px между ними. Мы можем использовать строки внутри столбца для вложенного макета.
Никогда не используйте столбец вне строки.
С учетом этих соображений мы можем идти вперед и создавать дизайн нашего первого макета.
Представление в терминологии Django —обычная функция Python, которая посылает на страницу запрос путем генерации перенаправляющей страницы. Для написания нашего первого представления Django для главной страницы, нам нужно сначала создать приложение Django внутри нашего проекта. Вы можете подумать о приложении как о контейнере для представлений и моделей данных. Для создания, выполните следующую команду из-под папки mytweets:
python manage.py startapp tweets
Синтаксис этой команды очень похож на процесс создания проекта. Мы используем команду startapp в качестве первого параметра команды python manage.py, tweets выступает в качестве имени нашего приложения.
После запуска этой команды, Django создаст каталог с именем tweets внутри нашего проекта с этими тремя файлами:
Теперь давайте создадим представление главной страницы. Сначала мы создадим каталог template внутри проекта для сохранения всех HTML-файлов:
mkdir templates
Теперь внутри нее создадим файл HTML с именем base.html и следующим содержимым:
{% load staticfiles %}
<html>
<head>
<link href="{% static 'bootstrap/css/bootstrap.min.css’ %}" rel="stylesheet" media="screen" />">
</head>
<body>
{% block content %}
<hl class="text-info">Привет, DJANGO!</hl>
{% endblock %}
<script src="{% static 'bootstrap/js/bootstrap.min.js' %}"></script> </body>
</html>
Сейчас наша структура директории будет выглядеть так (используйте команду tree , если вы работаете в операционной системе Linux ):
mytweets/
|-- manage.py
|-- mytweets
| |-- init .py
| |-- init .pyc
| |-- settings.py
| |-- settings.pyc
| |-- urls.py
| |-- urls.pyc
| |-- wsgi.py
| `--wsgi.pyc
|-- static
| | - - css
| | |-- bootstrap.css
| | |-- bootstrap.css.map
| | |-- bootstrap.min.css
| | |-- bootstrap-theme.css
| | |-~ bootstrap-theme.css.map
| | | '-- bootstrap-theme.min.css
|- - fonts
I --glyphicons-halflings-regular.eot
I--glyphicons-halflings-regular.svg
|-- glyphicons-halflings-regular.ttf
|--glyphicons-halflings-regular.woff
I js
|-- bootstrap.js | '-- bootstrap.min.js |-- templates | '-- base.html '-- tweets |-- admin.py
|-- init .py
|-- models.py |-- tests.py '-- views.py
Представления, основанные на классах – новый путь определения представлений на Django. Он не заменяет представления, основанные на функциях. Это просто альтернативный путь имплементации представлений как объектов Python вместо функций. Перед представлениями на основе функций есть два больших преимущества. При использовании представлений на основе классов разные HTTP- запросы могут отображаться в разные функции, в отличие от представлений на основе функций, где ветвление имеет место, основываясь на параметре request.method. Объектно-ориентированные технологии могут быть использованы для повторного использования кода компонента, такие как mixins.
Хотя мы будем использовать представления на основе классов для нашего проекта, чтобы понять разницу между этими двумя представлениями, здесь мы представим код для обоих вариантов.
Мы должны обновить файл urls.py нашего проекта так, что файл base.html будет предоставляться, если пользователь запрашивает веб-сайт.
Обновите файл views.py как показано:
from django.http import HttpResponse
def index(request): if request.method == 'GET':
return HttpResponse('Запрос получен')
elif request.method == 'POST':
return HttpResponse('Запрос опубликован')
Обновите файл urls. py, как показано:
from django.conf.urls import patterns, include, url
from django.contrib import admin
from tweets import views
admin.autodiscover()
urlpatterns = patterns (' ',
url(r'A$', views.index, name='index'),
url(r'Aadmin/', include(admin.site.urls)),
)
Запустите сервер разработки командой python manage.py runserver.
Мы увидим ответ: Запрос получен.
Обновите файл views.py как показано:
from django.http import HttpResponse
from django.views.generic import View
class Index(View):
def get(self, request):
return HttpResponse('Запрос получен')
def post(self, request):
return HttpResponse('Запрос опубликован')
urls.py
from django.conf.urls import patterns, include, url
from django.contrib import admin
from tweets.views import Index
admin.autodiscover()
urlpatterns = patterns('',
url(r'^$', Index.as_view()),
url(r'^admin/', include(admin.site.urls)),
)
Это создаст тот же результат в браузере после того, как мы попадем на сервер разработки. Мы будем использовать представления на основе класса во всем этом проекте.
То, что мы отобразили, это просто строка, это не так уж и сложно. Мы создали файл base.html в нашей папке шаблона и будем продвигаться вперед с представлениями на основе классов и отобразим наш файл base.html.
В Django существует более чем один способ отобразить нашу страницу. Мы можем показать нашу страницу, используя любой из этих трех функций: render(), render_to_response() или direct_to_template().Однако давайте сначала посмотрим, какова разница между ними и как мы должны использовать каждую:
Однако следует избегать команды direct_to_template так как общие представления на основе функций являются устаревшими.
Мы выберем второй вариант, функцию render() для рендеринга нашего шаблона base.html.
Следующий шаг — включение каталога шаблона в нашем приложении Django (каталог template, который мы создали с основным файлом под именем base.html). Чтобы включить в шаблон, мы обновим файл settings.py следующим образом:
TEMPLATE_DIRS = ( BASE_DIR + '/templates/' ) TEMPLATE_LOADERS = ( 'django.template.loaders.filesystem.Loader', 'django.template.loaders.app_directories.Loader', )
Это определяет каталог шаблонов и инициализирует основные параметры template_loader.
Давайте обновим файл settings.py с минимальными настройками, которые нам нужны для нашего проекта mytweets. Прежде чем запускать наше приложение mytweets мы добавим множество параметров, которые мы можем увидеть в следующих изменениях. Для дополнительной информации об этом файле, посетите
https://docs.djangoproject.com/en/1.8/topics/settings/.
Для просмотра полного списка параметров и их значений, посетите
https://docs.djangoproject.com/en/1.8/ref/settings/
Обновите файл settings.py следующим содержимым:
# Стройте пути к проекту как здесь: os.path.join(BASE_DIR, ...)
import os
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
# Настройки разработчика для быстрого старта – для производства не годятся
# Посмотрите https://docs.djangoproject.com/en/1.6/howto/deployment/checklist/
# ПРЕДУПРЕЖДЕНИЕ БЕЗОПАСНОСТИ: Сохраняйте секретный ключ, используемый в производстве, в секрете!
SECRET_KEY = 'l@y^@ra9q(ws(amb*-$wyc_w@)1)s!p4r04rq9od$nr_*3!nx'
# ПРЕДУПРЕЖДЕНИЕ БЕЗОПАСНОСТИ: Не запускайте в производство, если режим отладки включен!
DEBUG = True
TEMPLATE_DEBUG = True
ALLOWED_HOSTS = ['127.0.0.1']
# Определение приложений
INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
)
MIDDLEWARE_CLASSES = (
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
)
ROOT_URLCONF = 'mytweets.urls'
WSGI_APPLICATION = 'mytweets.wsgi.application'
# База данных
# https://docs.djangoproject.com/en/1.6/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
STATICFILES_DIRS = (
os.path.join(
os.path.dirname(__file__),
'static',
),
)
TEMPLATE_DIRS = (
BASE_DIR + '/templates/',
)
# List of callables that know how to import templates from various sources.
TEMPLATE_LOADERS = (
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader',
)
# Internationalization
# https://docs.djangoproject.com/en/1.6/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.6/howto/static-files/
STATIC_URL = '/static/'
Теперь, если мы запустим наш сервер разработки, наш экран будет выглядеть так же как и на приведенном скриншоте:
Как мы можем отметить, в шаблоне нет никаких переменных, наличие которые отличает статические страницы, от динамических. Так давайте же сделаем это. Нам нужно внести изменения в файлы views.py и base.html, как показано ниже:
from django.views.generic import View
from django.shortcuts import render
class Index(View):
def get(self, request):
params = {}
params["name"] = "Django"
return render(request, 'base.html', params)
{% load staticfiles %}
<html>
<head>
<link href="{% static 'bootstrap/css/bootstrap.min.css' %}"
rel="stylesheet" media="screen">
</head>
<body>
{% block content %}
<h1>ПРИВЕТ {{name}}</h1>
{% endblock %}
<script src="{% static 'bootstrap/js/bootstrap.min.js' %}"></script>
</body>
</html>
Видите, как это просто. Все, что мы сделали это просто создали отображение (называемый в Python словарем) и назначили свойству name значение Django и добавили его в функцию render () как новый параметр. Он отрисовывается в основе HTML и легко называется {{name}}. Когда он показывается, он заменяется на Django.
Мы зафиксируем все изменения, что до сих пор сделали. Прежде чем мы сделаем это, давайте создадим файл .gitignore, Все, что он делает, независимо от содержимого этого файла( или подстановки для файлов, которые мы описали внутри файла.gitignore), он предотвратит их от подтверждения изменений и посылает их на сервер подтверждения.
Как это поможет? Это может помочь во многих важных случаях использования. Предположим, что мы не хотим отправлять любые локальные файлы конфигурации на рабочий сервере. Файл .gitignore может быть спасением в таких ситуациях, а также в случае когда файлы .py генерируют свои файлы .pyc, которые компилируются во время выполнения. Нам не нужны эти двоичные файлы на сервере, так как они будут создаваться каждый раз заново при изменении кода
В командной строке Linux просто введите команду $ vim .gitignore в корне каталога c проектом и записать туда *. pyc. Затем, сохраните и выйдите как обычно.
Теперь, если мы выполняем команду git status, мы не увидим ни одного файла с расширением pyc, что означает, что Git игнорирует отслеживания файлов, которые заканчиваются расширением .pyc.
Результат выполнения команды git status может быть следующим:
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working di-rectory)
modified: mytweets/settings.py
modified: mytweets/urls.py
Untracked files:
(use "git add <file>..." to include in what will be committed)
.gitignore
.idea/
db.sqlite3
mytweets/settings.zip
templates/
tweets/
no changes added to commit (use "git add" and/or "git commit -a")
Почти чисто, но так и должно быть. Мы ранее подтверждали файлы settings.py и urls.py, а теперь внесли в них изменения, а в Git для отслеживания не добавили.
Мы используем команду git add . для добавления всех изменений в каталоге. Конечно, для предотвращения ситуации, когда Git отслеживает нежелательные файлы лучше добавлять их по одному, но мы рассмотрим это в продвинутой части разработки. Для добавления требуемого файла в проект, выполните команду:
git add .
Вывод будет следующим:
On branch master Changes to be committed: (use "git reset HEAD <file>..." to unstage) new file: .gitignore modified: mytweets/settings.py modified: mytweets/urls.py new file: static/css/bootstrap-theme.css new file: static/css/bootstrap-theme.css.map new file: static/css/bootstrap-theme.min.css new file: static/css/bootstrap.css new file: static/css/bootstrap.css.map new file: static/css/bootstrap.min.css new file: static/fonts/glyphicons-halflings-regular.eot new file: static/fonts/glyphicons-halflings-regular.svg new file: static/fonts/glyphicons-halflings-regular.ttf new file: static/fonts/glyphicons-halflings-regular.woff new file: static/js/bootstrap.js new file: static/js/bootstrap.min.js new file: templates/base.html new file: tweets/ init .py new file: tweets/admin.py new file: tweets/models.py new file: tweets/tests.py new file: tweets/views.py
Подтвердите изменения соответствующим сообщением, например "Новое подтверждение".
git commit -m " Новое подтверждение" [master 195230b] Новое подтверждение 21 files changed, 9062 inser-tions(+), 1 deletion(-) create mode 100644 .gitignore create mode 100644 static/css/bootstrap-theme.css create mode 100644 static/css/bootstrap-theme.css.map create mode 100644 static/css/bootstrap-theme.min.css create mode 100644 static/css/bootstrap.css create mode 100644 static/css/bootstrap.css.map create mode 100644 static/css/bootstrap.min.css create mode 100644 static/fonts/glyphicons-halflings-regular.eot create mode 100644 static/fonts/glyphicons-halflings-regular.svg create mode 100644 static/fonts/glyphicons-halflings-regular.ttf create mode 100644 static/fonts/glyphicons-halflings-regular .woff create mode 100644 static/js/bootstrap.js create mode 100644 static/js/bootstrap.min.js create mode 100644 templates/base.html create mode 100644 tweets/ init .py create mode 100644 tweets/admin.py create mode 100644 tweets/models.py create mode 100644 tweets/tests.py create mode 100644 tweets/views.py
Итак, мы осветили кучу материала, такую как введение в концепции представлений и шаблонов. В заключительном разделе мы напишем еще одно представление и сможем использовать информацию, которую мы узнали. Это представление отобразит список всех твитов, принадлежащих пользователю.
Модели – это обычные классы Python с некоторыми дополнительными возможностями. Они являются подклассами django.db.models.Model. За кадром, объектно-реляционное отображение (ORM), связана с этими классами и объектами. Это связывает ее с подлежащей базой данных. ORM одна из важных возможностей Django, без которой мы не смогли бы закончить наши собственные запросы (SQL или MySQL) для доступа к содержимому базы данных. Каждый атрибут модели представляется полем базы данных. Без этих полей, модель будет подобна пустому контейеру, без них она ничего не значит.
Ниже приведено объяснение атрибутов модели Django c отступлением по их использованию. Полный список полей может быть найден на страницах документации: https://docs.djangoproject.com/en/dev/ref/models/fields
Ниже приведен перечень часто используемых типов полей:
| Тип поля | Описание |
|---|---|
| IntegerField | Целое число. |
| TextField | Поле для большого текста |
| DateTimeField | Поле дата-время |
| EmailField | Поле для электронной почты, максимум 75 символов |
| URLField | Поле для URL-адреса, максимум 200 символов |
| FileField | Поле загружаемого файла |
Каждое поле модели принимает набор аргументов конкретного поля. Например если мы хотим,, чтобы поле было типа CharField, мы должны предъявить параметр max_length в качестве его аргумента, который сопоставляется с размером поля в переменной varchar в базе данных.
Ниже приведены аргументы, которые могут быть применены ко всем типам полей (они необязательны):
Разница между параметрами blank и null связана с тем, что параметр null в основном связан с базой данных, тогда как параметр blank используется для проверки поля. Другими словами, если атрибут установлен в false, пустое значение (blank) для атрибута не будет сохраняться.
Например:
USER_ROLE = (
('U',’ПОЛЬЗОВАТЕЛЬ’),
('S ',' СОТРУДНИКИ '),
('A', 'АДМИНИСТРАТОР')
)
user_role = models.CharField(max_length=l, choice s=USER_ROLE)
Есть три основных типа отношений: многие-ко-многим, многие-к-одному и один-к-одному.
В Django, параметр django.db.models.ForeignKey используется для определения модели как внешнего ключа к атрибуту другой модели, чьи результаты связаны отношениями многие-ко многим.
Этот атрибут используется, как и любой другой в классе модели, после включения класса, в котором он присутствует. Например если учащиеся учаться в конкретной школе, между ними связь такова, что в школе многоо учащихся, каждый учещийся учится только в одной школе, создавая отношения многие-к-одному. Рассмотрим следующий фрагмент кода:
from django.db import models
class School(models.Model):
#...
ass
class Student(models.Model):
school = models.ForeignKey(School)
# ...
Отношения один-к-одному очень похожи на отношения многие к одному. Единственное отличие состоит в том, что обратное отображение результатов в одном объекте в случае отношений один к одному противоположно отношениям многие к одному. Например:
class EntryDetail(models.Model): entry = models.OneToOneField(Entry) details = models.TextField()
В приведенном примере класс EntryDetail() имеет атрибут с именем entry который сопоставлен с моделью Entry отношением один-к-одному. Это означает, что каждый объект модели Entry отображается в модель EntryDetail.
Как можно предположить по названию, атрибуты модели с отношениями многие-ко-многим обеспечивают доступ к обеим моделям, к которым они прикреплены (как обратная связь один-ко-многим). Именование атрибутов означает только разницу между двумя отношениями.
Чтобы все было ясно, рассмотрим следующий пример:
class Product(models.Model):
name = models.CharField(_(u"Name"), max_length=50)
class Category(models.Model):
name = models.CharField(_(u"Name"), max_length=50)
products = models.ManyToManyField("Product", blank=True, null=True)
С идеей атрибута и первичных отношений мы можем сразу создать модель длянашего проекта, чем мы скоро и займемся в следующих разделах.
Если мы соберемся проектировать модель для приложения, мы должны разбить приложения, если в них слишком много моделей. Если у нас есть более чем примерно 15 моделей в приложении, мы должны думать о том, как разбить наше приложение на небольшие приложения. Это связано с тем, что если у нас существует приложение с 15-ю моделями, мы вероятно все усложнили. Это не подходит к философии Django о том, что приложение должно выполнять одну задачу и выполнять ее правильно.
Возвращаясь к нашему проекту, на начальном этапе нам нужно две модели для нашего проекта модель user и модель tweet. Модель user будет использоваться для хранения основных подробностей о пользователях, которые будут иметь аккаунты в нашей системе.
Затем мы обращаемся к модели tweet, которая будет хранить все данные относящиеся к твиту, такие как текст твита, пользователь, создавший твит и другие важные подробности , такие как временной штамп опубликованного твита и т.д.
Для просмотра твитов пользователя, лучше создать отдельное приложение, особое для всех пользователей проекта. Наши пользовательские модели будут созданы на основе расширенного класса пользовательской модели Django AbstractBaseUser.
Изменение текущего класса user в вашем дереве источников Django, а также копирование и изменение модуля auth никогда не рекомендуется.
Это будет первое приложение с использованием фреймворка для веб-разработки, вместо написания всей системы аутентификации самостоятельно, что является довольно общим для всех сценариев веб-разработки. Django поставляется со стандартными библиотеки так, что нам не нужно снова изобретать колесо. В поставке так же есть аутентификация и авторизация вместе и это называется система аутентификации
Дополнительная настраиваемая модель пользователя поставляется с Django 1.5, что является более простым методом для хранения пользовательских данных в приложении.
Мы создадим приложение user и затем импортируем модель пользователя Django по умолчанию:
python manage.py startapp user_profile
Мы будем расширять модель пользователя Django согласно нашим потребностям в текущем проекте, создав пользовательский класс User(), который наследует от класса AbstractBaseUser. Таким образом наш файл models.py будет выглядеть так:
from django.db import models from django.contrib.auth.models import AbstractBaseUser class User(AbstractBaseUser):
Теперь, когда мы создали наш класс user для данного проекта, мы можем добавить все основные атрибуты к данному классу user, которые нам бы хотелось видеть в данной модели,
Наш файл models.py будет выглядеть так:
from django.db import models
from django.contrib.auth.models import AbstractBaseUser
class User(AbstractBaseUser):
username = models.CharField( 'username', max_length=10, unique=True, db_index=True)
email = models.EmailField('email address', unique=True)
joined = models.DateTimeField(auto_now_add=True)
is_active = models.BooleanField(default=True)
is_admin = models.BooleanField(default=False)
В приведенном коде поле пользовательской модели email имеет свойство unique, установленное в True. Это означает, что пользователь может зарегистрироваться, предоставив свой адрес электронной почты, подтверждение может быть сделано на странице регистрации. Вы также можете заметить опцию db_index в атрибуте username со значением в True, которая будет индексировать таблицу пользователя в атрибуте username.
Параметр joined типа DateTimeField автоматически увеличивается, когда создается новый профиль пользователя.; поле is_active по умолчанию устанавливается в True при создании нового аккаунта, а поле is_admin в то же самое время устанавливается в False.
Еще одно поле, которое нам необходимо сделать, чтобы у нас получилось почти то же самое, что и в модели пользователя Django по умолчанию, поле username.
Добавьте поле USERNAME_FIELD в файл models.py:
USERNAME_FIELD = 'username'
def __unicode__(self):
return self.username
USERNAME_FIELD выступает также в качестве уникального идентификатора для пользовательской модели в Django. Мы сопоставляем параметр username с полем username Django. Это поле должно быть уникальным по своему определению (unique=True), когда наше поле username уже существует.
Метод __unicode__() так же добавляется как определение, которое отображается в формате, удобном для представления человеку объекта нашей модели пользователя.
Итак, окончательный вариант нашего файла models.py будет выглядеть так:
from django.db import models
from django.contrib.auth.models import AbstractBaseUser
class User(AbstractBaseUser):
username = models.CharField( 'username', max_length=10, unique=True, db_index=True)
email = models.EmailField('email address', unique=True)
joined = models.DateTimeField(auto_now_add=True)
is_active = models.BooleanField(default=True)
is_admin = models.BooleanField(default=False)
USERNAME_FIELD = 'username'
def __unicode__(self):
return self.username
Теперь, после определения нашей модели пользователя, мы можем перейти к дальнейшей разработке модели твита. это будет такое же приложение, которое мы создавали для проверки основного представления на основе классов.
Мы добавим следующее в файл models.py приложения tweets:
from django.db import models from user_profile.models import User class Tweet(models.Model): user = models.ForeignKey(User) text = models.CharField(max_length=160) created_date = models.DateTimeField(auto_now_add=True) country = models.CharField(max_length=30) is_active = models.BooleanField(default=True)
Модель твита разработана максимально просто для пользователя. Параметр user – это внешний ключ для объекта User, который мы уже создавали. Атрибут text – это содержимое твита, содержит в основном простой текст. Атибут created_date автоматически добавляется в базу данных, когда инициализируется объект tweet. Country хранит имя страны, из которой опубликован твит, в большинстве случаев он совпадает со страной проживания пользователя. Флаг is_active используется для представления текущего состояния твита, когда тот активен и может отображаться, и удаляться пользователем.
Нам нужно создать таблицы в базе данных для обоих созданных моделей, user_profile и tweets. Нам нужно обновить переменную INSTALLED_APPS в файле settings.py для указания Django включить эти приложения в состав нашего проекта.
Наша обновленная переменная INSTALLED_APPS будет выглядеть так:
INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'user_profile',
'tweets'
)
Вы можете обратить внимание, что последние две строки добавляют две созданные нами модели.
Сейчас мы создадим таблицу базы данных для нашего проекта, для чего запустим следующую команду из-под корневого каталога проекта в командной строке:
python manage.py syncdb
Вывод может быть следующим:
C:\Python34\lib\site-packages\django\core\management\commands\syncdb.py:24: Removed In Django 1.9 Warning: The syncdb command will be removed in Django 1.9
warnings.warn("The syncdb command will be removed in Django 1.9", RemovedInDja
ngo19Warning)
Operations to perform:
Synchronize unmigrated apps: staticfiles, messages
Apply all migrations: sessions, contenttypes, auth, admin
Synchronizing apps without migrations:
Creating tables...
Running deferred SQL...
Installing custom SQL...
Running migrations:
No migrations to apply.
Your models have changes that are not yet reflected in a migration, and so won
't be applied.
Run 'manage.py makemigrations' to make new migrations, and then rerun 'manage
.py migrate' to apply them.
Вы только что установили систему авторизации Django, что подразумевает отсутствие созданных суперпользователей. Вы увидите следующее приглашение:
You have installed Django's auth system, and don't have any superusers defined. Would you like to create one now? (yes/no): yes Username (leave blank to use 'ff'): sergioalvares Email address: tilllindemann85@outlook.com Password: Password (again): Superuser created successfully.
В результате, к нашей базе данных добавится таблица. Она появится в базе данных, в файле нашего проекта, названном db.sqlite3.
Как и в случае с Django 1.6, панель администратора поставляется по умолчанию. Все что нам нужно для того, чтобы модели были доступны в администраторской панели Django, это добавить параметр admin.site.register с именем модели в качестве аргумента для обоих приложений.
Таким образом, после добавления admin.site.register(parameter) в файлы admin.py обоих приложений, tweets и user_profile, будут выглядеть следующим образом:
from django.contrib import admin from models import Tweet admin.site.register(Tweet)
from django.contrib import admin from models import User admin.site.register(User)
Запустим сервер командой:
python manage.py runserver
Перейдя по адресу http: //127.0.0.1:8000/admin, мы получим запрос информации о входе. Как вы помните, мы создавали пользователя по умолчанию во время запуска команды python manage.py syncdb; используйте те же логин и пароль.
После успешного входа, администраторская панель будет выглядеть как на приведенном скриншоте:
Давайте поиграем с панелью управления администратора и создадим объекты user и tweet, которые мы используем далее для представления нашей домашней страницы. Для добавления нового пользователя к нашему проекту просто нажмите на кнопку Add перед полем модели пользователя, как показано на следующем скриншоте:
Затем заполните детали и сохраните их. Вы увидите сообщение user successfully created, как показано на следующем скриншоте:
Похожим образом создается твит. Давайте вернемся к http: //127.0.0.1:8000/admin. Затем нажмем кнопку Add напротив окошка Tweet.
Создайте новый твит, заполнив параметры и выбрав пользователя из выпадающего списка. Этот список пользователя уже заполнен, так как мы сопоставили пользователя с объектом user. Пока мы добавляем новых пользователей, выпадающий список будет пополняться новыми пользователями.
Наконец, после составления твита, нажмем на кнопку Save. Вы увидите то же, что и на следующем скриншоте:
Если вы присмотритесь внимательно, страница списка администратора говорит о том, что каждый твит есть объект tweet, представление которого не особенно дружелюбно к пользователю. Это можно легко исправить в данном случае. Действительно, это же правило применимо для всех базовых представлений моделей в представлении администратора Django или там, где они отображаются.
Добавим следующий фрагмент в файл admin.py нашего проекта:
def __unicode__(self):
return self.text
Каждый пользователь в нашем проекте будет иметь профиль с уникальным URL-адресом в следующем формате: http://127.0.0.1:8000/user/<username>. Здесь имя переменной username – владелец твитов, которого мы хотим видеть. Этот URL-адрес отличается от первоначального URL-адреса, который мы добавили ранее, поскольку он содержит динамическую часть, поэтому мы должны использовать мощь регулярных выражений для того, чтобы описать этот URL. Откройте файл urls.py и измените его таким образом, чтобы таблица URL-адресов выглядит так:
from django.conf.urls import patterns, include, url
from django.contrib import admin
from tweet.views import Index,Profile
admin.autodiscover()
urlpatterns = patterns('',
url(r'^$', Index.as_view()),
url(r'^user/(\w+)/$', Profile.as_view()),
url(r'^admin/', include(admin.site.urls)),
)
Шаблон выглядит более сложным, чем первый. Аннотация \w означает цифробуквенный символ или знак подчеркивания. Знак + после него, вызывает регулярные выражение для сопоставления одного или более повторений того, что предшествует знаку. Так в сущности, \w+ означает любую строку, которая состоит из буквенно-цифровых символов и, возможно, символа подчеркивания. Мы заключили эту часть регулярного выражения в скобки. Это заставляет Django захватить часть строки, которая совпадает с этой частью и отправляете его в представление.
Последняя вещь требует объяснения, прежде чем мы увидим представление в действии. Регулярное выражение, которое мы использовали будет выглядеть немного странно, если вы не использовали регулярные выражения раньше. Это Raw String, которая содержит два символа, ^ и $. Аннотации r ' ' в синтаксисе Python обозначает raw string. Если Python встречает такую строку, обратная косая черта и другие управляющие последовательности, сохраняются в строке, а не интерпретируются любым другим способом. В этом синтаксисе обратные косые черты остаются в строке без изменения, а управляющие последовательности не интерпретируются . Это очень полезно при работе с регулярными выражениями потому, что они часто содержат обратные косые черты.
В регулярных выражениях, ^ означает начало строки, а $ означает конец строки. Поэтому ^$ означает строку, не содержащую ничего, то есть пустую строку. Действительно мы пишем представление главной страницы, URL-адрес страницы является корневым URL-адресом, и он действительно должен быть пустым.
Документация Python по модулю re полностью покрывает все регулярные выражения. Я рекомендую прочитать ее, если вы хотите тщательного разбираться в регулярных выражениях. Вы можете найти онлайн-документацию на http://docs.python.org/lib/module-re.html. Перед вами таблица, в которой обобщается синтаксис регулярных выражений для тех, кто хочет быстро освежить свои знания:
| Символ/выражение | Совпадающая строка |
|---|---|
| . (Точка) | Любой символ |
| ^ (Каретка) | Начало строки |
| $ | Конец строки |
| * | 0 или более повторений |
| + | 1 или более повторений |
| ? | 0 или 1 повторение |
| | | A | B означает A или B |
| [a-z] | Любая буква в нижнем регистре |
| \w | Любой цифробуквенный символ или _ _ |
| \d | Любая цифра |
Сейчас мы создадим класс Profile() с функцией GET в файле views.py нашего приложения для твитов. Важное, что мы узнаем, это как функция get () function прикрепляет динамический параметр проходящий через URL-адрес , который связан с переменной username.
Файл views.py нашего приложения для твитов будет выглядеть так:
class Profile(View): """User Profile page reachable from /user/<username> URL""" def get(self, request, username): params = dict() user = User.objects.get (username=usemame) tweets = Tweet.objects.filter(user=user) params["tweets"] = tweets params["user"] = user return render(request, 'profile.html', params)
Мы почти завершили создание главной страницы для нашего сайта. Теперь мы двинемся дальше и создадим страницу представления.
Первая страница, которую мы создадим, это основная страница, которая отображает список твитов, опубликованных пользователем. Это может быть так называемая страница открытого профиля, к которой можно получить доступ без аутентификации.
Как мы могли отметить, мы использовали файл profile.html в классе Profile() нашего файла views.py, принадлежащий нашему приложению твитов.
Файл views.py нашего приложения для твитов будет выглядеть так:
class Profile(View): """User Profile page reachable from /user/<username> URL""" def get(self, request, username): params = dict() user = User.objects.get (username=usemame) tweets = Tweet.objects.filter(user=user) params["tweets"] = tweets params["user"] = user return render(request, 'profile.html', params)
Мы используем фреймворк Bootstrap, который мы уже импортировали в наш файл base.html, теперь мы создадим файл profile.html.
Мы перестроим структуру файла base.html, который мы создали для нашего приложения. Сейчас файл base.html будет использован в качестве шаблона или темы для нашего проекта. Мы импортируем этот файл в наш проект, который покажет непостоянный интерфейс пользователя через весь проект.
Мы удалим тег div, который мы поместили внутри содержимого блока в нашем файле base.html.
Нам также, понадобится jQuery, который является библиотекой для полного функционирования bootstrap. Его можно скачать с http://jquery.com/download/. Для нашего текущего проекта, мы скачаем последнюю версию jQuery в стадии рабочей готовности. Мы добавим это перед импортом JavaScript’а bootstrap.
Файл base.html должен выглядеть так:
{% load staticfiles %}
<html>
<head>
link href="{% static 'bootstrap/css/bootstrap.min.css' %}" rel="stylesheet" media="screen">
</head>
<body>
{% block content %}
{% endblock %}
<script src="{% static 'js/jquery-2.1.1.min.js' %}"></script>
<script src="{% static 'bootstrap/js/bootstrap.min.js'
%}"></script>
</body>
</html>
В данном случае, блок будет выглядеть так:
{% block content %}
{% endblock %}
Это означает, что какой бы шаблон мы не использовали для расширения нашего файла base.html в текущем файле profile. html,содержимое файла profile. html отобразится между этим фрагментом блока. Чтобы понять это лучше, усвойте одно: у вас есть заголовок (в некоторых случаях панель навигации) и подвал на каждой странице и содержимое страницы изменяется в зависимости от представления. С предыдущим шаблоном нам, в общем, нужно разместить код заголовка перед содержимым блока, а содержимое подвала после содержимого блока.
Использовать заголовок намного проще сейчас, когда у нас есть преимущество в виде фронтэнд фреймворка. Сперва мы выберем подложку для нашего проекта. Чтобы было проще объяснить, мы разделим страницу на три части. Первая – это заголовок, которая остается постоянным при навигации по проекту. То же применительно к нижней части проекта, где находится подвал.
Для достижения предыдущей структуры, наш код bootstrap будет построен таким образом: мы будем использовать navbar bootstrap’а для нашего раздела заголовка, а так же как и для раздела подвала, Затем мы поместим контейнер тега div. Обновим наш файл base.html в соответствии с нижеследующим:
{% load staticfiles %}
<html>
<head>
<link href="{% static 'css/bootstrap.min.css' %}"
rel="stylesheet" media="screen">
</head>
<body>
<nav class="navbar navbar-default navbar-fixed-top" role="navigation">
<a class="navbar-brand" href="#">Мои твиты</a>
<p class="navbar-text navbar-right">Страница профиля пользователя</p>
</nav>
<div class="container">
{% block content %}
{% endblock %}
</div>
<nav class="navbar navbar-default navbar-fixed-bottom" role="navigation">
<p class="navbar-text navbar-right">Подвал </p>
</nav>
<div class="container">
</nav>
<script src="{% static 'js/bootstrap.min.js' %}"></script>
</body>
</html>
Параметр navbar начинается с тела, но перед контейнером, так что возможно обернуть весь контейнер. Мы используем блок содержимого Django для отображения строк, которые мы определим в расширенных шаблонах, в данном случае, в файле profile.html. Подвал идет последним, сразупосле оператора endblock.
Отобразится следующая страница:
Заметьте, что если вы не у вас не включились статические файлы, замените переменную STATICFILES_DIRS следующими настройками файла settings.py:
STATICFILES_DIRS = ( BASE_DIR + '/ static /’, )
Дизайн для профиля страницы выглядит следующим образом:
Его легко изменить нова с помощью компонента boostrap, называемого well. Компоненты well или wellbox используются с элементом чтобы дать ему эффект врезки. Файл profile.html просто расширяет файл base.html и содержит строки и другие элементы.
Файл profile.html для нашего проекта будет выглядеть так:
{% extends "base.html" %}
{% block content %}
<div class="row clearfix">
<div class="col-md-12 column">
{% for tweet in tweets %}
<div class="well">
<span>{{ tweet.text }}</span>
</div>
{% endfor %}
</div>
</div>
{% endblock %}
Это покажет наши твиты через параметр в URL-адресе пользователя. Пример, который мы взяли это пользователь test, который мы создали в ходе первоначальной установки. Вы можете увидеть его твиты на следующем скриншоте:
Контрольные вопросы
Упражнения
Упражнение 1.
Измените расположение навигационной панели главной страницы с горизонтального на вертикальное
Упражнение 2.
Создайте нового пользователя и опубликуйте от его имени несколько твитов.
Упражнение 3.
Замените навигационную панель на главной странице на выпадающее меню.
Упражнение 4.
Загрузите какой либо репозиторий с проектом Django через систему контроля версий Git и запустите сервер разработки с данным проектом
Список тем, эссе
Краткие итоги
Цель лекции: Рассмотреть основную терминологию Django; создать основную страницу приложения; создать структуру шаблона проекта на Django; настроить основной загрузчик для приложения, создать шаблон основной страницы.
Ключевые термины: django, bootstrap, файл, html, проект, css, class, python, user, admin, модель, страница, представление, приложение, пользователь
Django – это фреймворк, построенный на технологии MVC. На протяжении всего кода контроллер называется представлением, а представление называется шаблоном. Представление в Django – это компонент, который получает и манипулирует данными, а шаблон – это компонент, представляющий данные пользователю. По этой причине Django называют Модель-Шаблон-Представление (MTV) фреймворк. Эта разница не отменяет того факта, что Django является MVC фреймворком, не влияет на разработку приложений, но для предотвращения возможных коллизий требуется держать эту терминологию в голове, если вы соберетесь использовать MVC фреймворк.
Вы думаете, что эта глава – глубокое погружение в основные компоненты Django. Вы узнаете, как создавать динамические страницы, с помощью представлений, как хранить и управлять данными в базе данных с помощью моделей и как упростить генерацию страниц, с помощью шаблонов.
В процессе изучения этих особенностей, вы сформируете фундаментальную идею о том, как работают компоненты Django и взаимодействуют друг с другом. В более поздних главах, мы изучим эти компоненты более глубоко, когда разработаем больше возможностей и добавим их в приложение.
Наш проект собирается быть микроблогинговым сайтом, где у каждого пользователя будет общедоступная страница, на которой разместятся твиты в хронологическом порядке.
Первое, что приходит в голову при виде начальной страницы сервера разработки – это вопрос, как можно изменить ее. Чтобы создать собственную начальную страницу, нам нужно определить точку входа для нашего приложения в форме URL-адреса и указать Django вызвать особую функцию Python, когда посетитель обращается к данному URL. Мы напишем эту функцию Python сами и отобразим наше собственное приветственное сообщение.
В этом разделе в основном повторение конфигурации, сделанной в предыдущей главе, но наша цель здесь – собрать все инструкции вместе здесь, так что начальная загрузка проекта займет меньше страниц.
Мы настроим виртуальное окружение на правильную работу Django, используя следующую команду:
virtualenv djangoenv
Вы получите следующий вывод:
Using base prefix 'c:\\python34' New python executable in djangoenv\Scripts\python.exe Installing setuptools, pip, wheel...done.
Теперь нам нужно активировать виртуальное окружение и настроить все переменные среды таким образом, чтобы всё установленное Python будет перенаправляться в это окружение, не затрагивая другие параметры:
djangoenv\Scripts\activate
Вывод может быть следующим:
(djangoenv) C:\new1>
Хотя мы уже и устанавливали Django, мы сделаем это снова, потому что Django управляется virtualenv, которая не может разрешить работать другим пользователям или проектам (или себе самому) работать поверх него.
pip install django
Вы можете получить следующую ошибку:
bad interpreter: No such file or directory
Если такая ошибка получена, то создаем виртуальное окружение внутри пути без пробелов. Это быть потому, что в пути к расположению, где вы создали свое виртуальное окружение, существует каталог, чье имя содержит пробел, например,
/home/sergio/folder name with space$virtualenv djangoenv.
Если это так, то измените имя каталогу на что-то похожее на это:
/home/sergio/folder_name_with_no_space$virtualenv djangoenv
Теперь мы можем продолжить установку Django, используя команду pip install django. Вывод может выглядеть следующим образом:
Collecting django Using cached Django-1.8.4-py2.py3-none-any.whl Installing collected packages: django Successfully installed django-1.8.4
Теперь прежде чем мы перейдем к созданию нашего приложения Django, мы убедимся, что установили Git. Чтобы узнать установленную версию Git, используйте следующую команду:
git --version
Вывод может быть следующим:
git version 1.9.1
Это подтверждает, что мы установили Git. Конечно же, вы можете спросить, будем ли мы использовать систему контроля версий для этого проекта, и наш ответ: Да. По мере продвижения вперед, мы будем использовать систему контроля версий для большинства файлов проекта.
В этом разделе мы создадим структуру для нашего проекта, к примеру, создадим каталог для нашего проекта с названием mytweets, установим необходимый пакет для нашего проекта и т.д. Выполним следующую команду:
django-admin.py startproject mytweets
Эта команда создаст каталог под названием mytweets, который мы будем использовать в качестве каталога нашего проекта. В текущем каталоге мы увидим два вложенных каталога: environment и mytweets. Вопрос заключается в том, собираемся ли мы включить эти два каталога в систему контроля версий? Мы не будем этого делать, потому что эти файлы являются весьма специфическими для вашей текущей системы. Они никак не помогут настроить такое же окружение, как наше. Кроме этого, есть и другой способ сделать это в Python: с помощью команды pip freeze. Эта команда делает моментальный снимок всех текущих библиотек, установленных в приложении Django, и вы можете их список в текстовый файл и использовать в системе контроля версий. Таким образом, ваш юный разработчик может скачать ту же версию библиотек. Не правда ли, путь Python решает?
Самый распространенный метод для установки новых пакетов – использование команды pip. Есть три версии команды pip install, и они представлены ниже:
pip install PackageName
Это команда по умолчанию и устанавливает последнюю версию пакета
pip install PackageName==l.0.4
Используя параметр ==, можно установвить конкретную версию пакета. В данном случае, это версия 1.0.4.
pip install 'PackageName>=1.0.41 # minimum version
Используйте эту команду, когда вы не уверены в устанавливаемой версии пакета, которую хотите установить, но помните о том, что вам нужна минимальная версия библиотеки.
Легко использовать команду pip для установки библиотек. Вы можете это сделать, использовав следующую команду:
pip install -r requirements.txt
Теперь необходимо "заморозить" библиотеки:
pip freeze > requirements.txt
Это "замораживает" библиотеки, установленные для проекта с номером версии, и сохраняет их в файл с именем requirements.txt.
На этой стадии нашего проекта действие команды freeze выглядит примерно так:
Django==l.6.5 argparse==l.2.1 wsgiref == 0.1.2
Для обратной установки этих библиотек в ваше только что созданное окружение с проектом, мы можем запустить следующую команду:
pip install -r requirements.txt
Теперь мы можем приступить к инициализации нашей директории с кодом в виде репозитория Git и изменить текущий путь на $cd mytweets. Выполните следующую команду для построения репозитория Git в каталоге вашего проекта:
git init
Результат будет следующим:
Initialized empty Git repository in C:\new1\mytweets\.git\
Если мы запустим все команды на системе, основанной на Linux для подробного вывода списка каталога мы увидим следующий вывод:
drwxrwxr-x 7 sergio sergio 4096 Aug 2 16:07 .git/
Это каталог .git, который, согласно соглашению об именах(начинается с точки) скрыт от обычного просмотра каталога, то есть, это каталог, где помещаются все связанные с Git файлы, такие как ветви, файлы, добавленные в промежуточную область, логи, и сохраняются. Удаление этого конкретного каталога сделает ваш каталог Git-свободным (свободным от контроля версий) и он становится таким же обычным каталогом, как любой другой каталог в вашей текущей системе.
Мы можем добавить все наши текущие файлы в каталог промежуточной области, используя следующую команду:
$git add .
Используйте следующую команду, для первого подтверждения проекта:
git commit -m "Начальная промежуточная версия проекта."
Вывод может быть следующим:
[master (root-commit) 00f3f54] Первоначальная промежуточная версия проекта warning: LF will be replaced by CRLF in manage.py. The file will have its original line endings in your working directory. warning: LF will be replaced by CRLF in mytweets/settings.py. The file will have its original line endings in your working directory. warning: LF will be replaced by CRLF in mytweets/urls.py. The file will have its original line endings in your working directory. warning: LF will be replaced by CRLF in mytweets/wsgi.py. The file will have its original line endings in your working directory. 5 files changed, 149 insertions(+) create mode 100644 manage.py create mode 100644 mytweets/__init__.py create mode 100644 mytweets/settings.py create mode 100644 mytweets/urls.py create mode 100644 mytweets/wsgi.py C:\new1\mytweets>
Первая строка (здесь это master) говорит о том, что мы в ветке master, а другие строки о том. какие файлы попали в промежуточную область.
Итак, мы настроили основной шаблон Django и добавили его в систему контроля версий. то же может быть проверено с помощью следующей команды:
git log
Вывод может быть следующим:
commit 00f3f542089ffbaaf88df3e085fbdba10c1a3525 Author: ratan <tilllindemann85@outlook.com> Date: Tue Sep 1 18:32:22 2015 +0300 Первоначальная промежуточная версия проекта
Инструкции по настройке автора и генерации SSH-ключей для выгрузки на удаленный репозиторий могут быть найдены по следующим ссылкам:
https://help.github.com/articles/set-up-git https://help.github.com/artides/generating-ssh-keys
Как говорилось в предыдущей главе, bootstrap –основной фреймворк для дизайна пользовательского интерфейса. Мы предполагаем, что действовать будем вторым способом, а именно, скачиванием вручную файлов bootstrap и связывание их в каталог static.
Этот метод подразумевает, что мы не будем выполнять следующую команду:
pip install django-bootstrap3
Детализированная документация по этому внедрению может быть найдена на: http://django-bootstrap3.readthedocs.org/
Мы используем тот метод, который предполагает скачать файлы boostrap и распаковать их в каталог static нашего проекта.
Для начала мы должны скачать статические файлы boostrap по следующему официальному веб-адреса:
Перейдя по этой ссылке, вы найдете кнопку "Скачать". Нажав эту кнопку, нажмите на "Скачать Bootstrap". Это закачает на ваш компьютер файлы Bootstrap в формате zip. Вы скачаете файл с названием типа bootstrap-3.2.O-dist.zip. Распакуйте содержимое этого файла. После распаковки будет создана следующая структура в каталоге bootstrap- 3.2.O-dist:
I-- css |-- bootstrap.css |--bootstrap.css.map |--bootstrap.min.css |-- bootstrap-theme.css |-- bootstrap-theme.css.map |-- bootstrap-theme.min.css |-- fonts I *" glyphicons-halflings-regular.eot Iglyphicons-halflings-regular.svg I~~ glyphicons-halflings-regular.ttf Iglyphicons-halflings-regular.woff I-- js |-- bootstrap.js |-- boot strap.min.js
Особые для приложения статические файлы будут находиться в подкаталоге static внутри приложения. Django просматривает эти подкаталоги, исходя из настройки STATICFILES_DIRS.
Давайте обновим эти настройки для определения поддиректории статических файлов в файле settings.py.
Мы обновим файл нашего проекта settings.py, как принято использовать его с Twitter Bootstrap:
STATICFILES_DIRS = ( os.path.join( os.path.dirname( __files__ ), 'static' ), )
Теперь, переменная static будет папкой, в которой мы будем хранить файлы Bootstrap. Мы создадим папку static внутри наш каталога текущего проекта и скопируем все распакованные файлы bootstrap в эту папку.
Для целей разработки мы будем держать большую часть параметров, как эти, например, по умолчанию в базе данных SQLite; позже мы можем изменить это во время развертывания нашего тестового приложения на MySQL или любую другую базу данных по выбору.
Теперь прежде чем мы будем использовать bootstrap в наших проектах, есть некоторые основополагающие концепции, которые мы должны знать, чтобы понять bootstrap как фронтэнд фреймворк.
Bootstrap создает дизайн страниц, основанный на системе сетки, и есть три основных элемента сетки, а именно:
Контейнер также обеспечивает заполнение содержимого из углов браузера что они не касаются боковой стороны области просмотра. По умолчанию заполнение — 15 px. Вам никогда не нужен другой контейнер внутри контейнера. На следующем рисунке показана структура контейнера:
Строки имеют 15 px отрицательный отступ с каждой стороны, которая выталкивает их на верхнюю часть отступа в 15 px контейнера от границы. В результате они становятся отрицательными, и строка касается края контейнера, отрицательный отступ от стороны накладывается на отступ от границы. Таким образом строка не выталкивается отступом контейнера от границы. Никогда не используйте строку за пределами контейнера.
Столбцы снова имеют отступ от стороны 15 px, поэтому содержимое столбцов помещается на расстоянии 15 px от края области видимости контейнера.
Таким образом нам не нужен специальный отступ слева и справа для первого и последнего столбца. Теперь обеспечивается равномерный зазор в 15 px по всем столбцам.
Содержимое внутри столбца выталкивается в месторасположение столбцов, и они разделяются зазором в 30 px между ними. Мы можем использовать строки внутри столбца для вложенного макета.
Никогда не используйте столбец вне строки.
С учетом этих соображений мы можем идти вперед и создавать дизайн нашего первого макета.
Представление в терминологии Django —обычная функция Python, которая посылает на страницу запрос путем генерации перенаправляющей страницы. Для написания нашего первого представления Django для главной страницы, нам нужно сначала создать приложение Django внутри нашего проекта. Вы можете подумать о приложении как о контейнере для представлений и моделей данных. Для создания, выполните следующую команду из-под папки mytweets:
python manage.py startapp tweets
Синтаксис этой команды очень похож на процесс создания проекта. Мы используем команду startapp в качестве первого параметра команды python manage.py, tweets выступает в качестве имени нашего приложения.
После запуска этой команды, Django создаст каталог с именем tweets внутри нашего проекта с этими тремя файлами:
Теперь давайте создадим представление главной страницы. Сначала мы создадим каталог template внутри проекта для сохранения всех HTML-файлов:
mkdir templates
Теперь внутри нее создадим файл HTML с именем base.html и следующим содержимым:
{% load staticfiles %}
<html>
<head>
<link href="{% static 'bootstrap/css/bootstrap.min.css’ %}" rel="stylesheet" media="screen" />">
</head>
<body>
{% block content %}
<hl class="text-info">Привет, DJANGO!</hl>
{% endblock %}
<script src="{% static 'bootstrap/js/bootstrap.min.js' %}"></script> </body>
</html>
Сейчас наша структура директории будет выглядеть так (используйте команду tree , если вы работаете в операционной системе Linux ):
mytweets/
|-- manage.py
|-- mytweets
| |-- init .py
| |-- init .pyc
| |-- settings.py
| |-- settings.pyc
| |-- urls.py
| |-- urls.pyc
| |-- wsgi.py
| `--wsgi.pyc
|-- static
| | - - css
| | |-- bootstrap.css
| | |-- bootstrap.css.map
| | |-- bootstrap.min.css
| | |-- bootstrap-theme.css
| | |-~ bootstrap-theme.css.map
| | | '-- bootstrap-theme.min.css
|- - fonts
I --glyphicons-halflings-regular.eot
I--glyphicons-halflings-regular.svg
|-- glyphicons-halflings-regular.ttf
|--glyphicons-halflings-regular.woff
I js
|-- bootstrap.js | '-- bootstrap.min.js |-- templates | '-- base.html '-- tweets |-- admin.py
|-- init .py
|-- models.py |-- tests.py '-- views.py
Представления, основанные на классах – новый путь определения представлений на Django. Он не заменяет представления, основанные на функциях. Это просто альтернативный путь имплементации представлений как объектов Python вместо функций. Перед представлениями на основе функций есть два больших преимущества. При использовании представлений на основе классов разные HTTP- запросы могут отображаться в разные функции, в отличие от представлений на основе функций, где ветвление имеет место, основываясь на параметре request.method. Объектно-ориентированные технологии могут быть использованы для повторного использования кода компонента, такие как mixins.
Хотя мы будем использовать представления на основе классов для нашего проекта, чтобы понять разницу между этими двумя представлениями, здесь мы представим код для обоих вариантов.
Мы должны обновить файл urls.py нашего проекта так, что файл base.html будет предоставляться, если пользователь запрашивает веб-сайт.
Обновите файл views.py как показано:
from django.http import HttpResponse
def index(request): if request.method == 'GET':
return HttpResponse('Запрос получен')
elif request.method == 'POST':
return HttpResponse('Запрос опубликован')
Обновите файл urls. py, как показано:
from django.conf.urls import patterns, include, url
from django.contrib import admin
from tweets import views
admin.autodiscover()
urlpatterns = patterns (' ',
url(r'A$', views.index, name='index'),
url(r'Aadmin/', include(admin.site.urls)),
)
Запустите сервер разработки командой python manage.py runserver.
Мы увидим ответ: Запрос получен.
Обновите файл views.py как показано:
from django.http import HttpResponse
from django.views.generic import View
class Index(View):
def get(self, request):
return HttpResponse('Запрос получен')
def post(self, request):
return HttpResponse('Запрос опубликован')
urls.py
from django.conf.urls import patterns, include, url
from django.contrib import admin
from tweets.views import Index
admin.autodiscover()
urlpatterns = patterns('',
url(r'^$', Index.as_view()),
url(r'^admin/', include(admin.site.urls)),
)
Это создаст тот же результат в браузере после того, как мы попадем на сервер разработки. Мы будем использовать представления на основе класса во всем этом проекте.
То, что мы отобразили, это просто строка, это не так уж и сложно. Мы создали файл base.html в нашей папке шаблона и будем продвигаться вперед с представлениями на основе классов и отобразим наш файл base.html.
В Django существует более чем один способ отобразить нашу страницу. Мы можем показать нашу страницу, используя любой из этих трех функций: render(), render_to_response() или direct_to_template().Однако давайте сначала посмотрим, какова разница между ними и как мы должны использовать каждую:
Однако следует избегать команды direct_to_template так как общие представления на основе функций являются устаревшими.
Мы выберем второй вариант, функцию render() для рендеринга нашего шаблона base.html.
Следующий шаг — включение каталога шаблона в нашем приложении Django (каталог template, который мы создали с основным файлом под именем base.html). Чтобы включить в шаблон, мы обновим файл settings.py следующим образом:
TEMPLATE_DIRS = ( BASE_DIR + '/templates/' ) TEMPLATE_LOADERS = ( 'django.template.loaders.filesystem.Loader', 'django.template.loaders.app_directories.Loader', )
Это определяет каталог шаблонов и инициализирует основные параметры template_loader.
Давайте обновим файл settings.py с минимальными настройками, которые нам нужны для нашего проекта mytweets. Прежде чем запускать наше приложение mytweets мы добавим множество параметров, которые мы можем увидеть в следующих изменениях. Для дополнительной информации об этом файле, посетите
https://docs.djangoproject.com/en/1.8/topics/settings/.
Для просмотра полного списка параметров и их значений, посетите
https://docs.djangoproject.com/en/1.8/ref/settings/
Обновите файл settings.py следующим содержимым:
# Стройте пути к проекту как здесь: os.path.join(BASE_DIR, ...)
import os
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
# Настройки разработчика для быстрого старта – для производства не годятся
# Посмотрите https://docs.djangoproject.com/en/1.6/howto/deployment/checklist/
# ПРЕДУПРЕЖДЕНИЕ БЕЗОПАСНОСТИ: Сохраняйте секретный ключ, используемый в производстве, в секрете!
SECRET_KEY = 'l@y^@ra9q(ws(amb*-$wyc_w@)1)s!p4r04rq9od$nr_*3!nx'
# ПРЕДУПРЕЖДЕНИЕ БЕЗОПАСНОСТИ: Не запускайте в производство, если режим отладки включен!
DEBUG = True
TEMPLATE_DEBUG = True
ALLOWED_HOSTS = ['127.0.0.1']
# Определение приложений
INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
)
MIDDLEWARE_CLASSES = (
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
)
ROOT_URLCONF = 'mytweets.urls'
WSGI_APPLICATION = 'mytweets.wsgi.application'
# База данных
# https://docs.djangoproject.com/en/1.6/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
STATICFILES_DIRS = (
os.path.join(
os.path.dirname(__file__),
'static',
),
)
TEMPLATE_DIRS = (
BASE_DIR + '/templates/',
)
# List of callables that know how to import templates from various sources.
TEMPLATE_LOADERS = (
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader',
)
# Internationalization
# https://docs.djangoproject.com/en/1.6/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.6/howto/static-files/
STATIC_URL = '/static/'
Теперь, если мы запустим наш сервер разработки, наш экран будет выглядеть так же как и на приведенном скриншоте:
Как мы можем отметить, в шаблоне нет никаких переменных, наличие которые отличает статические страницы, от динамических. Так давайте же сделаем это. Нам нужно внести изменения в файлы views.py и base.html, как показано ниже:
from django.views.generic import View
from django.shortcuts import render
class Index(View):
def get(self, request):
params = {}
params["name"] = "Django"
return render(request, 'base.html', params)
{% load staticfiles %}
<html>
<head>
<link href="{% static 'bootstrap/css/bootstrap.min.css' %}"
rel="stylesheet" media="screen">
</head>
<body>
{% block content %}
<h1>ПРИВЕТ {{name}}</h1>
{% endblock %}
<script src="{% static 'bootstrap/js/bootstrap.min.js' %}"></script>
</body>
</html>
Видите, как это просто. Все, что мы сделали это просто создали отображение (называемый в Python словарем) и назначили свойству name значение Django и добавили его в функцию render () как новый параметр. Он отрисовывается в основе HTML и легко называется {{name}}. Когда он показывается, он заменяется на Django.
Мы зафиксируем все изменения, что до сих пор сделали. Прежде чем мы сделаем это, давайте создадим файл .gitignore, Все, что он делает, независимо от содержимого этого файла( или подстановки для файлов, которые мы описали внутри файла.gitignore), он предотвратит их от подтверждения изменений и посылает их на сервер подтверждения.
Как это поможет? Это может помочь во многих важных случаях использования. Предположим, что мы не хотим отправлять любые локальные файлы конфигурации на рабочий сервере. Файл .gitignore может быть спасением в таких ситуациях, а также в случае когда файлы .py генерируют свои файлы .pyc, которые компилируются во время выполнения. Нам не нужны эти двоичные файлы на сервере, так как они будут создаваться каждый раз заново при изменении кода
В командной строке Linux просто введите команду $ vim .gitignore в корне каталога c проектом и записать туда *. pyc. Затем, сохраните и выйдите как обычно.
Теперь, если мы выполняем команду git status, мы не увидим ни одного файла с расширением pyc, что означает, что Git игнорирует отслеживания файлов, которые заканчиваются расширением .pyc.
Результат выполнения команды git status может быть следующим:
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working di-rectory)
modified: mytweets/settings.py
modified: mytweets/urls.py
Untracked files:
(use "git add <file>..." to include in what will be committed)
.gitignore
.idea/
db.sqlite3
mytweets/settings.zip
templates/
tweets/
no changes added to commit (use "git add" and/or "git commit -a")
Почти чисто, но так и должно быть. Мы ранее подтверждали файлы settings.py и urls.py, а теперь внесли в них изменения, а в Git для отслеживания не добавили.
Мы используем команду git add . для добавления всех изменений в каталоге. Конечно, для предотвращения ситуации, когда Git отслеживает нежелательные файлы лучше добавлять их по одному, но мы рассмотрим это в продвинутой части разработки. Для добавления требуемого файла в проект, выполните команду:
git add .
Вывод будет следующим:
On branch master Changes to be committed: (use "git reset HEAD <file>..." to unstage) new file: .gitignore modified: mytweets/settings.py modified: mytweets/urls.py new file: static/css/bootstrap-theme.css new file: static/css/bootstrap-theme.css.map new file: static/css/bootstrap-theme.min.css new file: static/css/bootstrap.css new file: static/css/bootstrap.css.map new file: static/css/bootstrap.min.css new file: static/fonts/glyphicons-halflings-regular.eot new file: static/fonts/glyphicons-halflings-regular.svg new file: static/fonts/glyphicons-halflings-regular.ttf new file: static/fonts/glyphicons-halflings-regular.woff new file: static/js/bootstrap.js new file: static/js/bootstrap.min.js new file: templates/base.html new file: tweets/ init .py new file: tweets/admin.py new file: tweets/models.py new file: tweets/tests.py new file: tweets/views.py
Подтвердите изменения соответствующим сообщением, например "Новое подтверждение".
git commit -m " Новое подтверждение" [master 195230b] Новое подтверждение 21 files changed, 9062 inser-tions(+), 1 deletion(-) create mode 100644 .gitignore create mode 100644 static/css/bootstrap-theme.css create mode 100644 static/css/bootstrap-theme.css.map create mode 100644 static/css/bootstrap-theme.min.css create mode 100644 static/css/bootstrap.css create mode 100644 static/css/bootstrap.css.map create mode 100644 static/css/bootstrap.min.css create mode 100644 static/fonts/glyphicons-halflings-regular.eot create mode 100644 static/fonts/glyphicons-halflings-regular.svg create mode 100644 static/fonts/glyphicons-halflings-regular.ttf create mode 100644 static/fonts/glyphicons-halflings-regular .woff create mode 100644 static/js/bootstrap.js create mode 100644 static/js/bootstrap.min.js create mode 100644 templates/base.html create mode 100644 tweets/ init .py create mode 100644 tweets/admin.py create mode 100644 tweets/models.py create mode 100644 tweets/tests.py create mode 100644 tweets/views.py
Итак, мы осветили кучу материала, такую как введение в концепции представлений и шаблонов. В заключительном разделе мы напишем еще одно представление и сможем использовать информацию, которую мы узнали. Это представление отобразит список всех твитов, принадлежащих пользователю.
Модели – это обычные классы Python с некоторыми дополнительными возможностями. Они являются подклассами django.db.models.Model. За кадром, объектно-реляционное отображение (ORM), связана с этими классами и объектами. Это связывает ее с подлежащей базой данных. ORM одна из важных возможностей Django, без которой мы не смогли бы закончить наши собственные запросы (SQL или MySQL) для доступа к содержимому базы данных. Каждый атрибут модели представляется полем базы данных. Без этих полей, модель будет подобна пустому контейеру, без них она ничего не значит.
Ниже приведено объяснение атрибутов модели Django c отступлением по их использованию. Полный список полей может быть найден на страницах документации: https://docs.djangoproject.com/en/dev/ref/models/fields
Ниже приведен перечень часто используемых типов полей:
| Тип поля | Описание |
|---|---|
| IntegerField | Целое число. |
| TextField | Поле для большого текста |
| DateTimeField | Поле дата-время |
| EmailField | Поле для электронной почты, максимум 75 символов |
| URLField | Поле для URL-адреса, максимум 200 символов |
| FileField | Поле загружаемого файла |
Каждое поле модели принимает набор аргументов конкретного поля. Например если мы хотим,, чтобы поле было типа CharField, мы должны предъявить параметр max_length в качестве его аргумента, который сопоставляется с размером поля в переменной varchar в базе данных.
Ниже приведены аргументы, которые могут быть применены ко всем типам полей (они необязательны):
Разница между параметрами blank и null связана с тем, что параметр null в основном связан с базой данных, тогда как параметр blank используется для проверки поля. Другими словами, если атрибут установлен в false, пустое значение (blank) для атрибута не будет сохраняться.
Например:
USER_ROLE = (
('U',’ПОЛЬЗОВАТЕЛЬ’),
('S ',' СОТРУДНИКИ '),
('A', 'АДМИНИСТРАТОР')
)
user_role = models.CharField(max_length=l, choice s=USER_ROLE)
Есть три основных типа отношений: многие-ко-многим, многие-к-одному и один-к-одному.
В Django, параметр django.db.models.ForeignKey используется для определения модели как внешнего ключа к атрибуту другой модели, чьи результаты связаны отношениями многие-ко многим.
Этот атрибут используется, как и любой другой в классе модели, после включения класса, в котором он присутствует. Например если учащиеся учаться в конкретной школе, между ними связь такова, что в школе многоо учащихся, каждый учещийся учится только в одной школе, создавая отношения многие-к-одному. Рассмотрим следующий фрагмент кода:
from django.db import models
class School(models.Model):
#...
ass
class Student(models.Model):
school = models.ForeignKey(School)
# ...
Отношения один-к-одному очень похожи на отношения многие к одному. Единственное отличие состоит в том, что обратное отображение результатов в одном объекте в случае отношений один к одному противоположно отношениям многие к одному. Например:
class EntryDetail(models.Model): entry = models.OneToOneField(Entry) details = models.TextField()
В приведенном примере класс EntryDetail() имеет атрибут с именем entry который сопоставлен с моделью Entry отношением один-к-одному. Это означает, что каждый объект модели Entry отображается в модель EntryDetail.
Как можно предположить по названию, атрибуты модели с отношениями многие-ко-многим обеспечивают доступ к обеим моделям, к которым они прикреплены (как обратная связь один-ко-многим). Именование атрибутов означает только разницу между двумя отношениями.
Чтобы все было ясно, рассмотрим следующий пример:
class Product(models.Model):
name = models.CharField(_(u"Name"), max_length=50)
class Category(models.Model):
name = models.CharField(_(u"Name"), max_length=50)
products = models.ManyToManyField("Product", blank=True, null=True)
С идеей атрибута и первичных отношений мы можем сразу создать модель длянашего проекта, чем мы скоро и займемся в следующих разделах.
Если мы соберемся проектировать модель для приложения, мы должны разбить приложения, если в них слишком много моделей. Если у нас есть более чем примерно 15 моделей в приложении, мы должны думать о том, как разбить наше приложение на небольшие приложения. Это связано с тем, что если у нас существует приложение с 15-ю моделями, мы вероятно все усложнили. Это не подходит к философии Django о том, что приложение должно выполнять одну задачу и выполнять ее правильно.
Возвращаясь к нашему проекту, на начальном этапе нам нужно две модели для нашего проекта модель user и модель tweet. Модель user будет использоваться для хранения основных подробностей о пользователях, которые будут иметь аккаунты в нашей системе.
Затем мы обращаемся к модели tweet, которая будет хранить все данные относящиеся к твиту, такие как текст твита, пользователь, создавший твит и другие важные подробности , такие как временной штамп опубликованного твита и т.д.
Для просмотра твитов пользователя, лучше создать отдельное приложение, особое для всех пользователей проекта. Наши пользовательские модели будут созданы на основе расширенного класса пользовательской модели Django AbstractBaseUser.
Изменение текущего класса user в вашем дереве источников Django, а также копирование и изменение модуля auth никогда не рекомендуется.
Это будет первое приложение с использованием фреймворка для веб-разработки, вместо написания всей системы аутентификации самостоятельно, что является довольно общим для всех сценариев веб-разработки. Django поставляется со стандартными библиотеки так, что нам не нужно снова изобретать колесо. В поставке так же есть аутентификация и авторизация вместе и это называется система аутентификации
Дополнительная настраиваемая модель пользователя поставляется с Django 1.5, что является более простым методом для хранения пользовательских данных в приложении.
Мы создадим приложение user и затем импортируем модель пользователя Django по умолчанию:
python manage.py startapp user_profile
Мы будем расширять модель пользователя Django согласно нашим потребностям в текущем проекте, создав пользовательский класс User(), который наследует от класса AbstractBaseUser. Таким образом наш файл models.py будет выглядеть так:
from django.db import models from django.contrib.auth.models import AbstractBaseUser class User(AbstractBaseUser):
Теперь, когда мы создали наш класс user для данного проекта, мы можем добавить все основные атрибуты к данному классу user, которые нам бы хотелось видеть в данной модели,
Наш файл models.py будет выглядеть так:
from django.db import models
from django.contrib.auth.models import AbstractBaseUser
class User(AbstractBaseUser):
username = models.CharField( 'username', max_length=10, unique=True, db_index=True)
email = models.EmailField('email address', unique=True)
joined = models.DateTimeField(auto_now_add=True)
is_active = models.BooleanField(default=True)
is_admin = models.BooleanField(default=False)
В приведенном коде поле пользовательской модели email имеет свойство unique, установленное в True. Это означает, что пользователь может зарегистрироваться, предоставив свой адрес электронной почты, подтверждение может быть сделано на странице регистрации. Вы также можете заметить опцию db_index в атрибуте username со значением в True, которая будет индексировать таблицу пользователя в атрибуте username.
Параметр joined типа DateTimeField автоматически увеличивается, когда создается новый профиль пользователя.; поле is_active по умолчанию устанавливается в True при создании нового аккаунта, а поле is_admin в то же самое время устанавливается в False.
Еще одно поле, которое нам необходимо сделать, чтобы у нас получилось почти то же самое, что и в модели пользователя Django по умолчанию, поле username.
Добавьте поле USERNAME_FIELD в файл models.py:
USERNAME_FIELD = 'username'
def __unicode__(self):
return self.username
USERNAME_FIELD выступает также в качестве уникального идентификатора для пользовательской модели в Django. Мы сопоставляем параметр username с полем username Django. Это поле должно быть уникальным по своему определению (unique=True), когда наше поле username уже существует.
Метод __unicode__() так же добавляется как определение, которое отображается в формате, удобном для представления человеку объекта нашей модели пользователя.
Итак, окончательный вариант нашего файла models.py будет выглядеть так:
from django.db import models
from django.contrib.auth.models import AbstractBaseUser
class User(AbstractBaseUser):
username = models.CharField( 'username', max_length=10, unique=True, db_index=True)
email = models.EmailField('email address', unique=True)
joined = models.DateTimeField(auto_now_add=True)
is_active = models.BooleanField(default=True)
is_admin = models.BooleanField(default=False)
USERNAME_FIELD = 'username'
def __unicode__(self):
return self.username
Теперь, после определения нашей модели пользователя, мы можем перейти к дальнейшей разработке модели твита. это будет такое же приложение, которое мы создавали для проверки основного представления на основе классов.
Мы добавим следующее в файл models.py приложения tweets:
from django.db import models from user_profile.models import User class Tweet(models.Model): user = models.ForeignKey(User) text = models.CharField(max_length=160) created_date = models.DateTimeField(auto_now_add=True) country = models.CharField(max_length=30) is_active = models.BooleanField(default=True)
Модель твита разработана максимально просто для пользователя. Параметр user – это внешний ключ для объекта User, который мы уже создавали. Атрибут text – это содержимое твита, содержит в основном простой текст. Атибут created_date автоматически добавляется в базу данных, когда инициализируется объект tweet. Country хранит имя страны, из которой опубликован твит, в большинстве случаев он совпадает со страной проживания пользователя. Флаг is_active используется для представления текущего состояния твита, когда тот активен и может отображаться, и удаляться пользователем.
Нам нужно создать таблицы в базе данных для обоих созданных моделей, user_profile и tweets. Нам нужно обновить переменную INSTALLED_APPS в файле settings.py для указания Django включить эти приложения в состав нашего проекта.
Наша обновленная переменная INSTALLED_APPS будет выглядеть так:
INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'user_profile',
'tweets'
)
Вы можете обратить внимание, что последние две строки добавляют две созданные нами модели.
Сейчас мы создадим таблицу базы данных для нашего проекта, для чего запустим следующую команду из-под корневого каталога проекта в командной строке:
python manage.py syncdb
Вывод может быть следующим:
C:\Python34\lib\site-packages\django\core\management\commands\syncdb.py:24: Removed In Django 1.9 Warning: The syncdb command will be removed in Django 1.9
warnings.warn("The syncdb command will be removed in Django 1.9", RemovedInDja
ngo19Warning)
Operations to perform:
Synchronize unmigrated apps: staticfiles, messages
Apply all migrations: sessions, contenttypes, auth, admin
Synchronizing apps without migrations:
Creating tables...
Running deferred SQL...
Installing custom SQL...
Running migrations:
No migrations to apply.
Your models have changes that are not yet reflected in a migration, and so won
't be applied.
Run 'manage.py makemigrations' to make new migrations, and then rerun 'manage
.py migrate' to apply them.
Вы только что установили систему авторизации Django, что подразумевает отсутствие созданных суперпользователей. Вы увидите следующее приглашение:
You have installed Django's auth system, and don't have any superusers defined. Would you like to create one now? (yes/no): yes Username (leave blank to use 'ff'): sergioalvares Email address: tilllindemann85@outlook.com Password: Password (again): Superuser created successfully.
В результате, к нашей базе данных добавится таблица. Она появится в базе данных, в файле нашего проекта, названном db.sqlite3.
Как и в случае с Django 1.6, панель администратора поставляется по умолчанию. Все что нам нужно для того, чтобы модели были доступны в администраторской панели Django, это добавить параметр admin.site.register с именем модели в качестве аргумента для обоих приложений.
Таким образом, после добавления admin.site.register(parameter) в файлы admin.py обоих приложений, tweets и user_profile, будут выглядеть следующим образом:
from django.contrib import admin from models import Tweet admin.site.register(Tweet)
from django.contrib import admin from models import User admin.site.register(User)
Запустим сервер командой:
python manage.py runserver
Перейдя по адресу http: //127.0.0.1:8000/admin, мы получим запрос информации о входе. Как вы помните, мы создавали пользователя по умолчанию во время запуска команды python manage.py syncdb; используйте те же логин и пароль.
После успешного входа, администраторская панель будет выглядеть как на приведенном скриншоте:
Давайте поиграем с панелью управления администратора и создадим объекты user и tweet, которые мы используем далее для представления нашей домашней страницы. Для добавления нового пользователя к нашему проекту просто нажмите на кнопку Add перед полем модели пользователя, как показано на следующем скриншоте:
Затем заполните детали и сохраните их. Вы увидите сообщение user successfully created, как показано на следующем скриншоте:
Похожим образом создается твит. Давайте вернемся к http: //127.0.0.1:8000/admin. Затем нажмем кнопку Add напротив окошка Tweet.
Создайте новый твит, заполнив параметры и выбрав пользователя из выпадающего списка. Этот список пользователя уже заполнен, так как мы сопоставили пользователя с объектом user. Пока мы добавляем новых пользователей, выпадающий список будет пополняться новыми пользователями.
Наконец, после составления твита, нажмем на кнопку Save. Вы увидите то же, что и на следующем скриншоте:
Если вы присмотритесь внимательно, страница списка администратора говорит о том, что каждый твит есть объект tweet, представление которого не особенно дружелюбно к пользователю. Это можно легко исправить в данном случае. Действительно, это же правило применимо для всех базовых представлений моделей в представлении администратора Django или там, где они отображаются.
Добавим следующий фрагмент в файл admin.py нашего проекта:
def __unicode__(self):
return self.text
Каждый пользователь в нашем проекте будет иметь профиль с уникальным URL-адресом в следующем формате: http://127.0.0.1:8000/user/<username>. Здесь имя переменной username – владелец твитов, которого мы хотим видеть. Этот URL-адрес отличается от первоначального URL-адреса, который мы добавили ранее, поскольку он содержит динамическую часть, поэтому мы должны использовать мощь регулярных выражений для того, чтобы описать этот URL. Откройте файл urls.py и измените его таким образом, чтобы таблица URL-адресов выглядит так:
from django.conf.urls import patterns, include, url
from django.contrib import admin
from tweet.views import Index,Profile
admin.autodiscover()
urlpatterns = patterns('',
url(r'^$', Index.as_view()),
url(r'^user/(\w+)/$', Profile.as_view()),
url(r'^admin/', include(admin.site.urls)),
)
Шаблон выглядит более сложным, чем первый. Аннотация \w означает цифробуквенный символ или знак подчеркивания. Знак + после него, вызывает регулярные выражение для сопоставления одного или более повторений того, что предшествует знаку. Так в сущности, \w+ означает любую строку, которая состоит из буквенно-цифровых символов и, возможно, символа подчеркивания. Мы заключили эту часть регулярного выражения в скобки. Это заставляет Django захватить часть строки, которая совпадает с этой частью и отправляете его в представление.
Последняя вещь требует объяснения, прежде чем мы увидим представление в действии. Регулярное выражение, которое мы использовали будет выглядеть немного странно, если вы не использовали регулярные выражения раньше. Это Raw String, которая содержит два символа, ^ и $. Аннотации r ' ' в синтаксисе Python обозначает raw string. Если Python встречает такую строку, обратная косая черта и другие управляющие последовательности, сохраняются в строке, а не интерпретируются любым другим способом. В этом синтаксисе обратные косые черты остаются в строке без изменения, а управляющие последовательности не интерпретируются . Это очень полезно при работе с регулярными выражениями потому, что они часто содержат обратные косые черты.
В регулярных выражениях, ^ означает начало строки, а $ означает конец строки. Поэтому ^$ означает строку, не содержащую ничего, то есть пустую строку. Действительно мы пишем представление главной страницы, URL-адрес страницы является корневым URL-адресом, и он действительно должен быть пустым.
Документация Python по модулю re полностью покрывает все регулярные выражения. Я рекомендую прочитать ее, если вы хотите тщательного разбираться в регулярных выражениях. Вы можете найти онлайн-документацию на http://docs.python.org/lib/module-re.html. Перед вами таблица, в которой обобщается синтаксис регулярных выражений для тех, кто хочет быстро освежить свои знания:
| Символ/выражение | Совпадающая строка |
|---|---|
| . (Точка) | Любой символ |
| ^ (Каретка) | Начало строки |
| $ | Конец строки |
| * | 0 или более повторений |
| + | 1 или более повторений |
| ? | 0 или 1 повторение |
| | | A | B означает A или B |
| [a-z] | Любая буква в нижнем регистре |
| \w | Любой цифробуквенный символ или _ _ |
| \d | Любая цифра |
Сейчас мы создадим класс Profile() с функцией GET в файле views.py нашего приложения для твитов. Важное, что мы узнаем, это как функция get () function прикрепляет динамический параметр проходящий через URL-адрес , который связан с переменной username.
Файл views.py нашего приложения для твитов будет выглядеть так:
class Profile(View): """User Profile page reachable from /user/<username> URL""" def get(self, request, username): params = dict() user = User.objects.get (username=usemame) tweets = Tweet.objects.filter(user=user) params["tweets"] = tweets params["user"] = user return render(request, 'profile.html', params)
Мы почти завершили создание главной страницы для нашего сайта. Теперь мы двинемся дальше и создадим страницу представления.
Первая страница, которую мы создадим, это основная страница, которая отображает список твитов, опубликованных пользователем. Это может быть так называемая страница открытого профиля, к которой можно получить доступ без аутентификации.
Как мы могли отметить, мы использовали файл profile.html в классе Profile() нашего файла views.py, принадлежащий нашему приложению твитов.
Файл views.py нашего приложения для твитов будет выглядеть так:
class Profile(View): """User Profile page reachable from /user/<username> URL""" def get(self, request, username): params = dict() user = User.objects.get (username=usemame) tweets = Tweet.objects.filter(user=user) params["tweets"] = tweets params["user"] = user return render(request, 'profile.html', params)
Мы используем фреймворк Bootstrap, который мы уже импортировали в наш файл base.html, теперь мы создадим файл profile.html.
Мы перестроим структуру файла base.html, который мы создали для нашего приложения. Сейчас файл base.html будет использован в качестве шаблона или темы для нашего проекта. Мы импортируем этот файл в наш проект, который покажет непостоянный интерфейс пользователя через весь проект.
Мы удалим тег div, который мы поместили внутри содержимого блока в нашем файле base.html.
Нам также, понадобится jQuery, который является библиотекой для полного функционирования bootstrap. Его можно скачать с http://jquery.com/download/. Для нашего текущего проекта, мы скачаем последнюю версию jQuery в стадии рабочей готовности. Мы добавим это перед импортом JavaScript’а bootstrap.
Файл base.html должен выглядеть так:
{% load staticfiles %}
<html>
<head>
link href="{% static 'bootstrap/css/bootstrap.min.css' %}" rel="stylesheet" media="screen">
</head>
<body>
{% block content %}
{% endblock %}
<script src="{% static 'js/jquery-2.1.1.min.js' %}"></script>
<script src="{% static 'bootstrap/js/bootstrap.min.js'
%}"></script>
</body>
</html>
В данном случае, блок будет выглядеть так:
{% block content %}
{% endblock %}
Это означает, что какой бы шаблон мы не использовали для расширения нашего файла base.html в текущем файле profile. html,содержимое файла profile. html отобразится между этим фрагментом блока. Чтобы понять это лучше, усвойте одно: у вас есть заголовок (в некоторых случаях панель навигации) и подвал на каждой странице и содержимое страницы изменяется в зависимости от представления. С предыдущим шаблоном нам, в общем, нужно разместить код заголовка перед содержимым блока, а содержимое подвала после содержимого блока.
Использовать заголовок намного проще сейчас, когда у нас есть преимущество в виде фронтэнд фреймворка. Сперва мы выберем подложку для нашего проекта. Чтобы было проще объяснить, мы разделим страницу на три части. Первая – это заголовок, которая остается постоянным при навигации по проекту. То же применительно к нижней части проекта, где находится подвал.
Для достижения предыдущей структуры, наш код bootstrap будет построен таким образом: мы будем использовать navbar bootstrap’а для нашего раздела заголовка, а так же как и для раздела подвала, Затем мы поместим контейнер тега div. Обновим наш файл base.html в соответствии с нижеследующим:
{% load staticfiles %}
<html>
<head>
<link href="{% static 'css/bootstrap.min.css' %}"
rel="stylesheet" media="screen">
</head>
<body>
<nav class="navbar navbar-default navbar-fixed-top" role="navigation">
<a class="navbar-brand" href="#">Мои твиты</a>
<p class="navbar-text navbar-right">Страница профиля пользователя</p>
</nav>
<div class="container">
{% block content %}
{% endblock %}
</div>
<nav class="navbar navbar-default navbar-fixed-bottom" role="navigation">
<p class="navbar-text navbar-right">Подвал </p>
</nav>
<div class="container">
</nav>
<script src="{% static 'js/bootstrap.min.js' %}"></script>
</body>
</html>
Параметр navbar начинается с тела, но перед контейнером, так что возможно обернуть весь контейнер. Мы используем блок содержимого Django для отображения строк, которые мы определим в расширенных шаблонах, в данном случае, в файле profile.html. Подвал идет последним, сразупосле оператора endblock.
Отобразится следующая страница:
Заметьте, что если вы не у вас не включились статические файлы, замените переменную STATICFILES_DIRS следующими настройками файла settings.py:
STATICFILES_DIRS = ( BASE_DIR + '/ static /’, )
Дизайн для профиля страницы выглядит следующим образом:
Его легко изменить нова с помощью компонента boostrap, называемого well. Компоненты well или wellbox используются с элементом чтобы дать ему эффект врезки. Файл profile.html просто расширяет файл base.html и содержит строки и другие элементы.
Файл profile.html для нашего проекта будет выглядеть так:
{% extends "base.html" %}
{% block content %}
<div class="row clearfix">
<div class="col-md-12 column">
{% for tweet in tweets %}
<div class="well">
<span>{{ tweet.text }}</span>
</div>
{% endfor %}
</div>
</div>
{% endblock %}
Это покажет наши твиты через параметр в URL-адресе пользователя. Пример, который мы взяли это пользователь test, который мы создали в ходе первоначальной установки. Вы можете увидеть его твиты на следующем скриншоте:
Контрольные вопросы
Упражнения
Упражнение 1.
Измените расположение навигационной панели главной страницы с горизонтального на вертикальное
Упражнение 2.
Создайте нового пользователя и опубликуйте от его имени несколько твитов.
Упражнение 3.
Замените навигационную панель на главной странице на выпадающее меню.
Упражнение 4.
Загрузите какой либо репозиторий с проектом Django через систему контроля версий Git и запустите сервер разработки с данным проектом
Список тем, эссе
Краткие итоги
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.