Введение в Django

Создание аналога Twitter

Разбить на страницы
Показывать лекцию целиком

Цель лекции: Рассмотреть основную терминологию Django; создать основную страницу приложения; создать структуру шаблона проекта на Django; настроить основной загрузчик для приложения, создать шаблон основной страницы.

Ключевые термины: django, bootstrap, файл, html, проект, css, class, python, user, admin, модель, страница, представление, приложение, пользователь

Разговор о терминологии Django

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, мы сделаем это снова, потому что 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. Конечно же, вы можете спросить, будем ли мы использовать систему контроля версий для этого проекта, и наш ответ: Да. По мере продвижения вперед, мы будем использовать систему контроля версий для большинства файлов проекта.

Создание структуры шаблона проекта на Django

В этом разделе мы создадим структуру для нашего проекта, к примеру, создадим каталог для нашего проекта с названием 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

Настройка основного Twitter Bootstrap для нашего приложения

Как говорилось в предыдущей главе, bootstrap –основной фреймворк для дизайна пользовательского интерфейса. Мы предполагаем, что действовать будем вторым способом, а именно, скачиванием вручную файлов bootstrap и связывание их в каталог static.

Этот метод подразумевает, что мы не будем выполнять следующую команду:

pip install django-bootstrap3

Детализированная документация по этому внедрению может быть найдена на: http://django-bootstrap3.readthedocs.org/

Мы используем тот метод, который предполагает скачать файлы boostrap и распаковать их в каталог static нашего проекта.

Для начала мы должны скачать статические файлы boostrap по следующему официальному веб-адреса:

http://getbootstrap.com/

Перейдя по этой ссылке, вы найдете кнопку "Скачать". Нажав эту кнопку, нажмите на "Скачать 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 создает дизайн страниц, основанный на системе сетки, и есть три основных элемента сетки, а именно:

  • Контейнер: контейнер используется для задания основы всей веб-страницы, как правило, все компоненты bootstrap будут прямыми или вложенными дочерними объектами контейнера. Другими словами, контейнеры предоставляют широкие ограничения на гибкие изменения ширины. Когда изменяется разрешение экрана, контейнер, изменяет свою ширину по всему экрану. Столбцы и строки изменяются в процентном отношении пропорционально.

    Контейнер также обеспечивает заполнение содержимого из углов браузера что они не касаются боковой стороны области просмотра. По умолчанию заполнение — 15 px. Вам никогда не нужен другой контейнер внутри контейнера. На следующем рисунке показана структура контейнера:

  • Строка: строка находится внутри контейнера и содержит столбец. Иерархия для основного дизайна — это контейнер | строка | столбец. Строка также действует как каркас для столбцов, поэтому в ситуациях, где столбцы начинают выглядеть странно из-за выравнивания по умолчанию по левому краю, держите их отдельно сгруппированы, так что эта проблема не выходит за пределы строки.

    Строки имеют 15 px отрицательный отступ с каждой стороны, которая выталкивает их на верхнюю часть отступа в 15 px контейнера от границы. В результате они становятся отрицательными, и строка касается края контейнера, отрицательный отступ от стороны накладывается на отступ от границы. Таким образом строка не выталкивается отступом контейнера от границы. Никогда не используйте строку за пределами контейнера.

  • Колонки: столбцы имеют отступ от края в 15 px. Это означает, что столбцы на самом деле касаются края строки, которая уже касается края контейнера из-за свойства отрицания с контейнером, о котором говорилось ранее.
  • Столбцы снова имеют отступ от стороны 15 px, поэтому содержимое столбцов помещается на расстоянии 15 px от края области видимости контейнера.

    Таким образом нам не нужен специальный отступ слева и справа для первого и последнего столбца. Теперь обеспечивается равномерный зазор в 15 px по всем столбцам.

    Содержимое внутри столбца выталкивается в месторасположение столбцов, и они разделяются зазором в 30 px между ними. Мы можем использовать строки внутри столбца для вложенного макета.

    Никогда не используйте столбец вне строки.

    С учетом этих соображений мы можем идти вперед и создавать дизайн нашего первого макета.

    URL-адреса и представления – создание главной страницы.

    Представление в терминологии Django —обычная функция Python, которая посылает на страницу запрос путем генерации перенаправляющей страницы. Для написания нашего первого представления Django для главной страницы, нам нужно сначала создать приложение Django внутри нашего проекта. Вы можете подумать о приложении как о контейнере для представлений и моделей данных. Для создания, выполните следующую команду из-под папки mytweets:

    python manage.py startapp tweets

    Синтаксис этой команды очень похож на процесс создания проекта. Мы используем команду startapp в качестве первого параметра команды python manage.py, tweets выступает в качестве имени нашего приложения.

    После запуска этой команды, Django создаст каталог с именем tweets внутри нашего проекта с этими тремя файлами:

  • _init_.py: Этот файл говорит Python, что tweets это пакет Python
  • views.py: Этот файл будет содержать наши представления
  • models.py: Этот файл будет содержать наши модели данных
  • Теперь давайте создадим представление главной страницы. Сначала мы создадим каталог 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().Однако давайте сначала посмотрим, какова разница между ними и как мы должны использовать каждую:

  • render_to_response (template [, dictionary] [, context_instance] [, mimetype]): Команда render_to_response является стандартной функцией отображения, и используя RequestContext, мы задаем context_inst ance=RequestContext(request).
  • render(request, template [ , dictionary][, context_instance][, content_type] [, status] [, current_app]). Это новый ярлык для команды render_to_response и он доступен в Django, начиная с версии 1.3. Он автоматически использует RequestContext.
  • (direct_to_template): это общее представление. RequestContext используется автоматически и все параметры context_processor.
  • Однако следует избегать команды 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.

    Параметры Django для проекта mytweets

    Давайте обновим файл 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, как показано ниже:

  • Изменения в файле views.py:
    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)
    
  • Изменения в файле base.html:
    {% 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
    

    Собрать все вместе – создание страниц пользователя

    Итак, мы осветили кучу материала, такую как введение в концепции представлений и шаблонов. В заключительном разделе мы напишем еще одно представление и сможем использовать информацию, которую мы узнали. Это представление отобразит список всех твитов, принадлежащих пользователю.

    Знакомство с моделями Django

    Модели – это обычные классы 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 в базе данных.

    Ниже приведены аргументы, которые могут быть применены ко всем типам полей (они необязательны):

  • null: по умолчанию он имеет значение false. Когда установлен в true, в связанном поле в базе данных возможно хранить значение null
  • blank: по умолчанию он имеет значение false. Если задано значение true, связанное поле разрешено иметь значение пустое, хранящихся в базе данных.

    Разница между параметрами blank и null связана с тем, что параметр null в основном связан с базой данных, тогда как параметр blank используется для проверки поля. Другими словами, если атрибут установлен в false, пустое значение (blank) для атрибута не будет сохраняться.

  • choices: здесь может быть список или кортеж и он может быть перечисляемым. Если наличествует форма кортежа, первый элемент является значением, которое будет храниться в базе данных,а второе значение используется для отображения в виджетоподобной форме или в ModelChoiceField.

    Например:

    USER_ROLE = (
    
    ('U',’ПОЛЬЗОВАТЕЛЬ’),         
    ('S ',' СОТРУДНИКИ '),	
    ('A', 'АДМИНИСТРАТОР')
    )
    user_role = models.CharField(max_length=l, choice s=USER_ROLE)
    
  • default: значения, назначенные атрибуту, каждый раз, когда создается экземпляр объекта класса.
  • help_text: текстовая помощь, отображаемая в виде виджета.
  • primary_key: Если установлено в True, это поле создает первичный ключ для модели. Если первичный ключ в модели отсутствует, Django создаст целочисленное поле и пометит его как первичный ключ.
  • Отношения в моделях

    Есть три основных типа отношений: многие-ко-многим, многие-к-одному и один-к-одному.

    Отношения многие-к-одному

    В 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

    Дополнительная настраиваемая модель пользователя поставляется с 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, будут выглядеть следующим образом:

  • Файл admin.py в приложении tweets будет выглядеть так:
    from django.contrib import admin 
    from models import Tweet
    admin.site.register(Tweet)
    
  • Файл admin.py в приложении user_profile будет выглядеть так:
    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-адресов

    Каждый пользователь в нашем проекте будет иметь профиль с уникальным 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, который мы создали в ходе первоначальной установки. Вы можете увидеть его твиты на следующем скриншоте:

    Контрольные вопросы

  • На платформе Django вместо принципа МVС используется принцип "модель - шаблон - представление" (model-template-view МТV). Проведите сравнение и определите различия между МТV и МVС.
  • Что такое приложение admin платформы Django? Как разрешить ero использование? В чем состоит назначение приложения admin?
  • Что означает CSRF и почему в Django предусмотрены механизмы безопасности для предотвращения таких попыток?
  • Что такое объектно-реляционное отображение (ORM )?
  • Для чего требуется делать поле username?
  • Упражнения

    Упражнение 1.

    Измените расположение навигационной панели главной страницы с горизонтального на вертикальное

    Упражнение 2.

    Создайте нового пользователя и опубликуйте от его имени несколько твитов.

    Упражнение 3.

    Замените навигационную панель на главной странице на выпадающее меню.

    Упражнение 4.

    Загрузите какой либо репозиторий с проектом Django через систему контроля версий Git и запустите сервер разработки с данным проектом

    Список тем, эссе

  • ORM
  • модель - шаблон - представление
  • Шаблоны в Django
  • Значение стилей в веб-программировании
  • Основы работы с JQuery
  • Основные компоненты Bootstrap
  • Регулярные выражения и их применение в веб-разработке.
  • Модели в Django.Основные типы полей.
  • Настройка административного интерфейса в веб-программировании как фактор обеспечения безопасности сайта.
  • Twitter и его аналоги
  • Краткие итоги

  • Рассмотрели основную терминологию Django
  • Создали главную страницу приложения
  • Научились создавать представления на основе классов
  • Научились создавать представления на основе функций
  • Узнали об основных отношениях в моделях
  • Рассмотрели понятие шаблона
  • Создали шаблон главной страницы
  • Создали модель пользователя
  • Создали интерфейс администратора
  • Создали пользователей и твиты от их имени
  • Страницы:

    Цель лекции: Рассмотреть основную терминологию Django; создать основную страницу приложения; создать структуру шаблона проекта на Django; настроить основной загрузчик для приложения, создать шаблон основной страницы.

    Ключевые термины: django, bootstrap, файл, html, проект, css, class, python, user, admin, модель, страница, представление, приложение, пользователь

    Разговор о терминологии Django

    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, мы сделаем это снова, потому что 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. Конечно же, вы можете спросить, будем ли мы использовать систему контроля версий для этого проекта, и наш ответ: Да. По мере продвижения вперед, мы будем использовать систему контроля версий для большинства файлов проекта.

    Создание структуры шаблона проекта на Django

    В этом разделе мы создадим структуру для нашего проекта, к примеру, создадим каталог для нашего проекта с названием 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
    

    Настройка основного Twitter Bootstrap для нашего приложения

    Как говорилось в предыдущей главе, bootstrap –основной фреймворк для дизайна пользовательского интерфейса. Мы предполагаем, что действовать будем вторым способом, а именно, скачиванием вручную файлов bootstrap и связывание их в каталог static.

    Этот метод подразумевает, что мы не будем выполнять следующую команду:

    pip install django-bootstrap3

    Детализированная документация по этому внедрению может быть найдена на: http://django-bootstrap3.readthedocs.org/

    Мы используем тот метод, который предполагает скачать файлы boostrap и распаковать их в каталог static нашего проекта.

    Для начала мы должны скачать статические файлы boostrap по следующему официальному веб-адреса:

    http://getbootstrap.com/

    Перейдя по этой ссылке, вы найдете кнопку "Скачать". Нажав эту кнопку, нажмите на "Скачать 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 создает дизайн страниц, основанный на системе сетки, и есть три основных элемента сетки, а именно:

  • Контейнер: контейнер используется для задания основы всей веб-страницы, как правило, все компоненты bootstrap будут прямыми или вложенными дочерними объектами контейнера. Другими словами, контейнеры предоставляют широкие ограничения на гибкие изменения ширины. Когда изменяется разрешение экрана, контейнер, изменяет свою ширину по всему экрану. Столбцы и строки изменяются в процентном отношении пропорционально.

    Контейнер также обеспечивает заполнение содержимого из углов браузера что они не касаются боковой стороны области просмотра. По умолчанию заполнение — 15 px. Вам никогда не нужен другой контейнер внутри контейнера. На следующем рисунке показана структура контейнера:

  • Строка: строка находится внутри контейнера и содержит столбец. Иерархия для основного дизайна — это контейнер | строка | столбец. Строка также действует как каркас для столбцов, поэтому в ситуациях, где столбцы начинают выглядеть странно из-за выравнивания по умолчанию по левому краю, держите их отдельно сгруппированы, так что эта проблема не выходит за пределы строки.

    Строки имеют 15 px отрицательный отступ с каждой стороны, которая выталкивает их на верхнюю часть отступа в 15 px контейнера от границы. В результате они становятся отрицательными, и строка касается края контейнера, отрицательный отступ от стороны накладывается на отступ от границы. Таким образом строка не выталкивается отступом контейнера от границы. Никогда не используйте строку за пределами контейнера.

  • Колонки: столбцы имеют отступ от края в 15 px. Это означает, что столбцы на самом деле касаются края строки, которая уже касается края контейнера из-за свойства отрицания с контейнером, о котором говорилось ранее.
  • Столбцы снова имеют отступ от стороны 15 px, поэтому содержимое столбцов помещается на расстоянии 15 px от края области видимости контейнера.

    Таким образом нам не нужен специальный отступ слева и справа для первого и последнего столбца. Теперь обеспечивается равномерный зазор в 15 px по всем столбцам.

    Содержимое внутри столбца выталкивается в месторасположение столбцов, и они разделяются зазором в 30 px между ними. Мы можем использовать строки внутри столбца для вложенного макета.

    Никогда не используйте столбец вне строки.

    С учетом этих соображений мы можем идти вперед и создавать дизайн нашего первого макета.

    URL-адреса и представления – создание главной страницы.

    Представление в терминологии Django —обычная функция Python, которая посылает на страницу запрос путем генерации перенаправляющей страницы. Для написания нашего первого представления Django для главной страницы, нам нужно сначала создать приложение Django внутри нашего проекта. Вы можете подумать о приложении как о контейнере для представлений и моделей данных. Для создания, выполните следующую команду из-под папки mytweets:

    python manage.py startapp tweets

    Синтаксис этой команды очень похож на процесс создания проекта. Мы используем команду startapp в качестве первого параметра команды python manage.py, tweets выступает в качестве имени нашего приложения.

    После запуска этой команды, Django создаст каталог с именем tweets внутри нашего проекта с этими тремя файлами:

  • _init_.py: Этот файл говорит Python, что tweets это пакет Python
  • views.py: Этот файл будет содержать наши представления
  • models.py: Этот файл будет содержать наши модели данных
  • Теперь давайте создадим представление главной страницы. Сначала мы создадим каталог 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().Однако давайте сначала посмотрим, какова разница между ними и как мы должны использовать каждую:

  • render_to_response (template [, dictionary] [, context_instance] [, mimetype]): Команда render_to_response является стандартной функцией отображения, и используя RequestContext, мы задаем context_inst ance=RequestContext(request).
  • render(request, template [ , dictionary][, context_instance][, content_type] [, status] [, current_app]). Это новый ярлык для команды render_to_response и он доступен в Django, начиная с версии 1.3. Он автоматически использует RequestContext.
  • (direct_to_template): это общее представление. RequestContext используется автоматически и все параметры context_processor.
  • Однако следует избегать команды 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.

    Параметры Django для проекта mytweets

    Давайте обновим файл 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, как показано ниже:

  • Изменения в файле views.py:
    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)
    
  • Изменения в файле base.html:
    {% 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
    

    Собрать все вместе – создание страниц пользователя

    Итак, мы осветили кучу материала, такую как введение в концепции представлений и шаблонов. В заключительном разделе мы напишем еще одно представление и сможем использовать информацию, которую мы узнали. Это представление отобразит список всех твитов, принадлежащих пользователю.

    Знакомство с моделями Django

    Модели – это обычные классы 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 в базе данных.

    Ниже приведены аргументы, которые могут быть применены ко всем типам полей (они необязательны):

  • null: по умолчанию он имеет значение false. Когда установлен в true, в связанном поле в базе данных возможно хранить значение null
  • blank: по умолчанию он имеет значение false. Если задано значение true, связанное поле разрешено иметь значение пустое, хранящихся в базе данных.

    Разница между параметрами blank и null связана с тем, что параметр null в основном связан с базой данных, тогда как параметр blank используется для проверки поля. Другими словами, если атрибут установлен в false, пустое значение (blank) для атрибута не будет сохраняться.

  • choices: здесь может быть список или кортеж и он может быть перечисляемым. Если наличествует форма кортежа, первый элемент является значением, которое будет храниться в базе данных,а второе значение используется для отображения в виджетоподобной форме или в ModelChoiceField.

    Например:

    USER_ROLE = (
    
    ('U',’ПОЛЬЗОВАТЕЛЬ’),         
    ('S ',' СОТРУДНИКИ '),	
    ('A', 'АДМИНИСТРАТОР')
    )
    user_role = models.CharField(max_length=l, choice s=USER_ROLE)
    
  • default: значения, назначенные атрибуту, каждый раз, когда создается экземпляр объекта класса.
  • help_text: текстовая помощь, отображаемая в виде виджета.
  • primary_key: Если установлено в True, это поле создает первичный ключ для модели. Если первичный ключ в модели отсутствует, Django создаст целочисленное поле и пометит его как первичный ключ.
  • Отношения в моделях

    Есть три основных типа отношений: многие-ко-многим, многие-к-одному и один-к-одному.

    Отношения многие-к-одному

    В 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

    Дополнительная настраиваемая модель пользователя поставляется с 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, будут выглядеть следующим образом:

  • Файл admin.py в приложении tweets будет выглядеть так:
    from django.contrib import admin 
    from models import Tweet
    admin.site.register(Tweet)
    
  • Файл admin.py в приложении user_profile будет выглядеть так:
    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-адресов

    Каждый пользователь в нашем проекте будет иметь профиль с уникальным 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, который мы создали в ходе первоначальной установки. Вы можете увидеть его твиты на следующем скриншоте:

    Контрольные вопросы

  • На платформе Django вместо принципа МVС используется принцип "модель - шаблон - представление" (model-template-view МТV). Проведите сравнение и определите различия между МТV и МVС.
  • Что такое приложение admin платформы Django? Как разрешить ero использование? В чем состоит назначение приложения admin?
  • Что означает CSRF и почему в Django предусмотрены механизмы безопасности для предотвращения таких попыток?
  • Что такое объектно-реляционное отображение (ORM )?
  • Для чего требуется делать поле username?
  • Упражнения

    Упражнение 1.

    Измените расположение навигационной панели главной страницы с горизонтального на вертикальное

    Упражнение 2.

    Создайте нового пользователя и опубликуйте от его имени несколько твитов.

    Упражнение 3.

    Замените навигационную панель на главной странице на выпадающее меню.

    Упражнение 4.

    Загрузите какой либо репозиторий с проектом Django через систему контроля версий Git и запустите сервер разработки с данным проектом

    Список тем, эссе

  • ORM
  • модель - шаблон - представление
  • Шаблоны в Django
  • Значение стилей в веб-программировании
  • Основы работы с JQuery
  • Основные компоненты Bootstrap
  • Регулярные выражения и их применение в веб-разработке.
  • Модели в Django.Основные типы полей.
  • Настройка административного интерфейса в веб-программировании как фактор обеспечения безопасности сайта.
  • Twitter и его аналоги
  • Краткие итоги

  • Рассмотрели основную терминологию Django
  • Создали главную страницу приложения
  • Научились создавать представления на основе классов
  • Научились создавать представления на основе функций
  • Узнали об основных отношениях в моделях
  • Рассмотрели понятие шаблона
  • Создали шаблон главной страницы
  • Создали модель пользователя
  • Создали интерфейс администратора
  • Создали пользователей и твиты от их имени
  • Вернуться к учебному плану