Главная
Блог разработчиков phpBB
 
+ 17 предустановленных модов
+ SEO-оптимизация форума
+ авторизация через соц. сети
+ защита от спама

Мега-Учебник Flask, Часть 2: Образцы

Anna | 16.06.2014 | нет комментариев
Это вторая статья в серии, где я описываю свой навык написания веб-приложения на Python с применением микрофреймворка Flask.

Цель данного начальства — разработать достаточно функциональное приложение-микроблог, которое я за полным отсутствием оригинальности решил назвать microblog.

Содержание

Часть 1: Здравствуй, Мир! 
Часть 2: Образцы (эта статья)
Часть 3: Формы
Часть 4: База данных
Часть 5: Вход пользователей
Часть 6: Страница профиля и аватары
Часть 7: Unit-тестирование
Часть 8: Подписчики, контакты и друзья
Часть 9: Пагинация
Часть 10: Полнотекстовый поиск
Часть 11: Помощь e-mail
Часть 12: Реконструкция
Часть 13: Дата и время
Часть 14: I18n and L10n
Часть 15: Ajax
Часть 16: Отладка, тестирование и профилирование
Часть 17: Развертывание на Linux (даже на Raspberry Pi!)
Часть 18: Развертывание на Heroku Cloud

Короткое повторение

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

microblog
  flask
    <файлы виртуального окружения>
  app
    static
    templates
    __init__.py
    views.py
    tmp
    run.py

Для запуска приложения вы запускаете скрипт run.py, после этого открываете url http://localhost:5000 в вашем браузере.

Мы продолжим с того момента, где мы остановились, так что вам следует удостовериться, что вышеупомянутое приложение верно установлено и работает.

Для чего нам необходимы образцы

Разглядим то, как мы можем расширить наше маленькое приложение.
Мы хотим, Дабы на основной странице нашего приложения микроблогов был заголовок, тот, что приветствует вошедшего в систему пользователя, что крайне стандартно для приложений такого рода. Пока что игнорируем тот факт, что у нас нет пользователей в приложении, я предоставлю решение этой задачи в необходимый момент.

Простым средством итога большого и прекрасного заголовка было бы сменить нашу функцию представлений на выдачу html, приблизительно так:

from app import app

@app.route('/')
@app.route('/index')
def index():
    user = { 'nickname': 'Miguel' } # вымышленный пользователь
    return '''
<html>
  <head>
    <title>Home Page</title>
  </head>
  <body>
    <h1>Hello, '''   user['nickname']   '''</h1>
  </body>
</html>
'''

Испробуйте посмотреть как выглядит приложение в вашем браузере.

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

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

Образцы торопятся на поддержка

Не задумывались ли вы о том, что если бы вы могли удерживать раздельно логику вашего приложения и макет, либо представление ваших страниц было бы организовано куда отменнее? Вы даже можете нанять веб-дизайнера, Дабы сделать головокружительный сайт в то время, пока вы программируете его [сайта] поведение при помощи Python. Образцы помогут осуществить это распределение.

Напишем наш 1-й образец (файл app/templates/index.html):

<html>
  <head>
    <title>{{title}} - microblog</title>
  </head>
  <body>
      <h1>Hello, {{user.nickname}}!</h1>
  </body>
</html>

Как видно выше, мы легко написали стандартную HTML страничку, но с одним лишь различием: плейсхолдеры для динамического содержимого заключены в сегменты {{… }}

Сейчас разглядим применение образца в нашей функции представления (файл app/views.py):

from flask import render_template
from app import app

@app.route('/')
@app.route('/index')
def index():
    user = { 'nickname': 'Miguel' } # вымышленный пользователь
    return render_template("index.html",
        title = 'Home',
        user = user)

Запустите приложение на данном этапе, Дабы посмотреть как работают образцы. Если в вашем браузере отрисована страница, то вы можете сравнить ее начальный код с подлинным образцом.

Дабы отдать страницу, нам необходимо импортировать из Flask новую функцию под наименованием render_template. Эта функция принимает имя образца и список переменных доводов образца, а возвращает готовый образец с замененными доводами.

Под капотом: функция render_template вызывает шаблонизатор Jinja2, тот, что является частью фреймворка Flask. Jinja2 заменяет блоки {{…}} на соответствующие им значения, переданные как доводы образца.

Руководящие операторы в образцах

Образцы Jinja2 помимо прочего поддерживают руководящие операторы, переданные внутри блоков {%…%}. Давайте добавим оператор if в наш образец (файл app/templates/index.html):

<html>
  <head>
    {% if title %}
    <title>{{title}} - microblog</title>
    {% else %}
    <title>Welcome to microblog</title>
    {% endif %}
  </head>
  <body>
      <h1>Hello, {{user.nickname}}!</h1>
  </body>
</html>

Сейчас наш образец слегка поумнел. Если мы позабудем определить наименование страницы в функции представления, то вместо исключения образец предоставит нам собственное наименование. Вы спокойно можете удалить довод заголовка из вызова render_template в нашей функции представления, Дабы увидеть как работает оператор if.

Циклы в образцах

Вошедший в наше приложение пользователь наверно захочет увидеть недавние записи от пользователей из его контакт-листа на основной странице, давайте посмотрим как же это сделать.

В начале, мы провернем трюк, Дабы сделать несколько ненастоящих пользователей и несколько записей для отображения (файл app/views.py):

def index():
    user = { 'nickname': 'Miguel' } # вымышленный пользователь
    posts = [ # список выдуманных постов
        { 
            'author': { 'nickname': 'John' }, 
            'body': 'Beautiful day in Portland!' 
        },
        { 
            'author': { 'nickname': 'Susan' }, 
            'body': 'The Avengers movie was so cool!' 
        }
    ]
    return render_template("index.html",
        title = 'Home',
        user = user,
        posts = posts)

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

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

Посмотрим как сделать это, применяя руководящую конструкцию (файл app/templates/index.html):

<html>
  <head>
    {% if title %}
    <title>{{title}} - microblog</title>
    {% else %}
    <title>microblog</title>
    {% endif %}
  </head>
  <body>
    <h1>Hi, {{user.nickname}}!</h1>
    {% for post in posts %}
    <p>{{post.author.nickname}} says: <b>{{post.body}}</b></p>
    {% endfor %}
  </body>
</html>

Не так уж и сложно, правда? Проверим приложение и непременно проверим добавление нового содержимого в список записей.

Наследование образцов

Мы охватим еще одну тему, раньше чем завершить на сегодня.

Нашему приложению микроблогов нужна навигационная панель с несколькими ссылками сверху страницы. Там будут ссылки на редактирование вашего профиля, выход и т.д.

Мы можем добавить навигационную панель в наш образец index.html, но, как только наше приложение разрастется, нам потребуется огромнее образцов, и навигационную панель необходимо будет скопировать в всякий из них. Тогда вы обязаны удерживать все эти копии идентичными. Это может стать трудоемкой задачей, если у вас много образцов.

Взамен этого мы можем применять наследование в образцах Jinja2, которое разрешает нам переместить части макета страницы в всеобщий для всех базовый образец, из которого все остальные образцы будут наследоваться.

Сейчас определим базовый образец, тот, что включает в себя навигационную панель, а также логику заголовка, которую мы реализовали ранее (файл app/templates/base.html):

<html>
  <head>
    {% if title %}
    <title>{{title}} - microblog</title>
    {% else %}
    <title>microblog</title>
    {% endif %}
  </head>
  <body>
    <div>Microblog: <a href="/index">Home</a></div>
    <hr>
    {% block content %}{% endblock %}
  </body>
</html>

В этом образце мы применяли руководящий оператор block для определения места, куда могут быть вставлены дочерние образцы. Блокам даются уникальные имена.

Сейчас осталось изменить наш index.html так, Дабы он наследовался от base.html (файлapp/templates/index.html):

{% extends "base.html" %}
{% block content %}
<h1>Hi, {{user.nickname}}!</h1>
{% for post in posts %}
<div><p>{{post.author.nickname}} says: <b>{{post.body}}</b></p></div>
{% endfor %}
{% endblock %}

Сейчас только образец base.html отвечает за всеобщую конструкцию страницы. Мы убрали те элементы отсель и оставили только часть с содержимым. Блок extends устанавливает преемственную связь между двумя образцами, таким образом Jinja2 знает: если нам необходимо отдать index.html, то необходимо включить его в base.html. Два образца имеют совпадающие операторы block с именем content, именно следственно Jinja2 знает как cкомбинировать два образца в один. Когда мы будем писать новые образцы, то также станем создавать их как растяжения base.html

Заключительные слова

Если вы хотите сэкономить время, то приложение микроблога в нынешней стадии доступно тут:
Скачать microblog-0.2.zip

Учтите, что zip файл не содержит в себе виртуального окружения flask. Сделайте его сами, следуя инструкциям в первой части, позже этого вы сумеете запустить приложение.

В дальнейшей части серии мы взглянем на формы. Верю увидимся.

Мигель

Источник: programmingmaster.ru
Оставить комментарий
Форум phpBB, русская поддержка форума phpBB
Рейтинг@Mail.ru 2008 - 2017 © BB3x.ru - русская поддержка форума phpBB