Маршрутизація

Сучасні веб-додатки використовують «красиві» URL. Це допомагає людям запам'ятати ці URL, це особливо зручно для додатків, що використовуються з мобільних пристроїв з більш повільним мережевим з'єднанням. Якщо користувач може перейти відразу на бажану сторінку без попереднього відвідування початкової сторінки, він з більшою ймовірністю повернеться на цю сторінку, і в наступний раз.

Як ви побачили раніше, декоратор route() використовується для прив'язки функції до URL. Ось найпростіші приклади:

@app.route('/')  
def index():  
    return 'Index Page'   

@app.route('/hello')  
def hello():  
    return 'Hello World' 

Але це ще не все! Ви можете зробити певні частини URL динамічно мінливими і задіяти в функції кілька правил.

Правила для змінної частини

Щоб додати до URL-адреси змінні частини, можна виділити ці особливі частини як <variable_name>. Потім подібні частини передаються в вашу функцію в якості аргументу - у вигляді ключового слова. Також може бути використаний конвертер - за допомогою завдання правила такого виду <converter: variable_name>. Ось кілька цікавих прикладів:

@app.route('/user/<username>')  
def show_user_profile(username):  
    # показати профіль даного користувача  
    return 'User %s' % username   

@app.route('/post/<int:post_id>')  
def show_post(post_id):  
    # вивести повідомлення з даними id, id - ціле число  
    return 'Post %d' % post_id 

Існують наступні конвертери:

  • int приймаються цілочисельні значення
  • float як і int, тільки значення з плаваючою точкою
  • path подібно поведінці за замовчуванням, але допускаються слеші

Унікальні URL / перенаправлення

Правила для URL, що працюють в Flask, засновані на модулі маршрутизації Werkzeug. Цей модуль реалізований у відповідність з ідеєю забезпечення красивих і унікальних URL-адрес на основі історично потрапив в ужиток - з поведінки Apache і більш ранніх HTTP серверів.

Візьмемо два правила:

@app.route('/projects/')  
def projects():  
    return 'The project page'   

@app.route('/about')  
def about():  
    return 'The about page'

Хоч вони і виглядають досить схожими, є різниця у використанні слешу у визначенні URL. У першому випадку, канонічний URL має завершальну частину projects зі слешем в кінці. У цьому сенсі він схожий на папку в файловій системі. В даному випадку, при доступі до URL без слешу, Flask перенаправить до канонічного URL з завершальним слешем.

Однак, у другому випадку, URL визначений без слеша - як шлях до файлу на UNIX-подібних системах. Доступ до URL з завершальною косою рисою буде призводити до появи помилки 404 "Not Found".

Така поведінка дозволяє продовжити працювати з відносними URL, навіть якщо в кінці рядка URL пропущений слеш - відповідно до того, як працюють Apache та інші сервера. Крім того, URL-адреси залишаться унікальними, що допоможе пошуковим системам уникнути повторної переіндексації сторінки.

Побудова (генерація) URL

Раз Flask може шукати відповідності в URL, чи може він їх генерувати? Звичайно, так. Для побудови URL для специфічної функції, ви можете використовувати функцію url_for(). В якості першого аргументу вона приймає ім'я функції, крім того вона приймає ряд іменованих аргументів, кожен з яких відповідає змінній частині правила для URL. Невідомі змінні частини додаються до URL в якості параметрів запиту. Ось деякі приклади:

>>> from flask import Flask, url_for  
>>> app = Flask(__name__)  
>>> @app.route('/')  
... def index(): pass  
...  
>>> @app.route('/login')  
... def login(): pass  
...  
>>> @app.route('/user/<username>')  
... def profile(username): pass  
...  
>>> with app.test_request_context():  
...  print url_for('index')  
...  print url_for('login')  
...  print url_for('login', next='/')  
...  print url_for('profile' username='John Doe')  
...  
/  
/login  
/login?next=/  
/user/John%20Doe 

(Тут також використаний метод test_request_context(), про який буде пояснено нижче. Він просить Flask поводитися так, як він обробляє запит, навіть якщо ми взаємодіємо з ним через оболонку Python. Погляньте на нижченаведене пояснення. Локальні об'єкти контексту (context locals).

Навіщо вам може знадобитися формувати URL - и за допомогою функції їх звернення url_for () замість того, щоб жорстко задати їх у ваших шаблонах? Для цього є три вагомі причини:

  1. У порівнянні з жорстким завданням URL всередині коду зворотний порядок часто є більш наочним. Більш того, він дозволяє змінювати URL за один крок, і забути про необхідність змінювати URL всюди.
  2. Побудова URL буде прозоро для вас здійснювати екранування спеціальних символів і даних Unicode, так що вам не доведеться окремо мати з ними справи.
  3. Якщо ваш додаток не розміщено в кореневій папці URL root (а, скажімо, в /myapplication замість /), дану ситуацію потрібним для вас чином обробить функція url_for().

Методи HTTP

HTTP-протокол, на якому спілкуються веб-додатки може використовувати різні методи для доступу до URL-адресами. За замовчуванням, route відповідає лише на запити типу GET, але це можна змінити, додавши декоратор route() аргументом methods. Ось деякі приклади:

from flask import request   

@app.route('/login', methods=['GET', 'POST'])  
def login():  
    if request.method = = 'POST':  
        do_the_login()  
    else:  
        show_the_login_form() 

Якщо присутній метод GET, то автоматично буде додано і HEAD. Вам не доведеться мати справу з ним. Також, при цьому можна бути впевненим, що запити HEAD будуть оброблені відповідно до вимог HTTP RFC (документ з описом протоколу HTTP), так що вам не потрібно нічого знати про цю частину специфікації HTTP. Крім того, починаючи з Flask версії 0.6, для вас буде автоматично реалізований метод OPTIONS.

Не маєте поняття, що таке метод HTTP? Не хвилюйтеся, тут швидко вводять методи HTTP, і чому вони важливі. HTTP-метод (також часто званий командою) повідомляє серверу, що хоче зробити клієнт з запитуваної сторінкою. Дуже поширені такі методи:

  • GET - Браузер говорить серверу, щоб він просто отримав інформацію, що зберігається на цій сторінці, і відіслав її. Можливо, це найпоширеніший метод.
  • HEAD - Браузер просить сервер отримати інформацію, але його цікавить тільки заголовки, а не вміст сторінки. Програма передбачає обробити їх так само, як якщо б був отриманий запит GET, але без доставки фактичного вмісту. У Flask, вам зовсім не потрібно мати справу з цим методом, так як нижележащая бібліотека Werkzeug зробить все за вас.
  • POST - Браузер говорить серверу, що він хоче повідомити цього URL деяку нову інформацію, і що сервер повинен переконатися, що дані збережені і збережені в один раз. Зазвичай, аналогічним чином відбувається передача з HTML форм на сервер даних.
  • PUT - Схоже на POST, тільки сервер може викликати процедуру збереження кілька разів, перезаписуючи старі значення більше одного разу. Тут ви можете запитати, навіщо це потрібно, і є кілька вагомих причин, щоб робити це таким чином. Припустимо, під час передачі сталася втрата з'єднання: у цій ситуації система між браузером і сервером, нічого не порушуючи, може абсолютно спокійно отримати запит вдруге. З POST таке було б неможливо, тому що він може бути викликаний тільки один раз.
  • DELETE - Видалити інформацію, розташовану в зазначеному місці.
  • OPTIONS - Забезпечує швидкий спосіб з'ясування клієнтом підтримуваних для даного URL методів. Починаючи з Flask 0.6, це працює для вас автоматично.
  • Тепер найцікавіше: в HTML 4 і XHTML1, єдиними методами, якими форма може відправити серверу дані, є GET І POST. Але для JavaScript і майбутніх стандартів HTML ви також можете використовувати і інші методи. Крім того, останнім часом HTTP став досить популярним, і тепер браузери вже не єдині клієнти, що використовують HTTP. Наприклад, його використовують багато систем контролю версій.