Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Разработка веб-приложений с использованием фреймворка Flask. В 2 частях. Ч.2. Учебное пособие-1.pdf
Скачиваний:
2
Добавлен:
06.09.2026
Размер:
421 Кб
Скачать
☆

{

"data": { "users": [ ]

},

"status": "success"

}

Добавим функцию в файл manage.py, чтобы заполнить базу данных на-

чальными данными:

@cli.command()

def seed_db():

""" Заполняет базу данных."""

db.session.add(User(username='testname1',

email="testname1@gmail.com"))

db.session.add(User(

username='testname3',

email="testname3@flaskapp.com"))

db.session.commit()

Попробуем выполнить следующую команду:

$ docker-compose -f docker-compose-dev.yml

\ run users python manage.py seed_db

Убедимся, что можно получать информацию о пользователях в ответе

JSON, используя маршрут http://DOCKER_MACHINE_IP:5001/users.

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

1.7. ИСПОЛЬЗОВАНИЕ ШАБЛОНОВ JINJA

Вместо того, чтобы просто использовать JSON API, добавим в приложе-

ние возможность использовать шаблоны на стороне сервера.

Добавим новый обработчик маршрута в файл services/users/project/api/ users.py:

@users_blueprint.route('/', methods=['GET'])

def index():

return render_template('index.html')

Также обновим конфигурацию Blueprint:

users_blueprint = Blueprint('users', __name__, tem-

plate_folder='./templates')

28

При этом необходимо обязательно обновить и импорт:

from flask import Blueprint, jsonify, request, render_template

Затем добавим каталог templates в project/api и разместим в этом каталоге

файл index.html следующего содержания:

<!DOCTYPE html> <html>

<head>

<meta charset="utf-8"> <title>Flask on Docker</title> <!-- meta -->

<meta name="description" content=""> <meta name="author" content="">

<meta name="viewport" content="width=device-width,initial- scale=1"> <!-- styles -->

<link

href="//maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.

css"

rel="stylesheet"

>

{% block css %}{% endblock %} </head>

<body>

<div class="container"> <div class="row">

<div class="col-md-4"> <br> <h1>All Users</h1> <hr><br>

<form action="/" method="POST"> <div class="form-group">

<input

name="username" class="form-control input-lg" type="text" placeholder="Enter a username" required>

</div>

<div class="form-group"> <input

name="email" class="form-control input-lg"

type="email" placeholder="Enter an email address" required> </div>

<input

type="submit" class="btn btn-primary btn-lg btn-block"

29

value="Submit">

</form>

<br> <hr>

{% if users %} <ol>

{% for user in users %} <li>{{user.username}}</li> {% endfor %}

</ol>

{% else %}

<p>No users!</p>

{% endif %} </div>

</div>

</div>

</div>

<!-- scripts --> <script

type="text/javascript" src="//code.jquery.com/jquery-2.2.4.min.js" ></script>

<script

type="text/javascript"

src="//maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js " >

</script>

{% block js %}{% endblock %} </body>

</html>

Переходим к тестированию. Необходимо открыть браузер и перейти на

IP-адрес, связанный с контейнером testdriven-dev.

Напишем тест:

def test_main_no_users(self):

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

response = self.client.get('/')

self.assertEqual(response.status_code, 200)

self.assertIn(b'<h1>All Users</h1>', response.data)

self.assertIn(b'<p>No users!</p>', response.data)

Проверим, выполняется ли тест:

$ docker-compose -f docker-compose-dev.yml \

run users python manage.py test

30

Обновим обработчик маршрута, чтобы получить данные всех пользовате-

лей из базы данных и отправить их в шаблон. Начнём с написания теста:

def test_main_with_users(self):

"""Проверка, что основной маршрут ведет себя корректно, когда

пользователи были добавлены в базу данных."""

add_user('testname1', 'testname1@flaskapp.org')

add_user('testname2', 'testname2@flaskapp.com')

with self.client:

response = self.client.get('/')

self.assertEqual(response.status_code, 200)

self.assertIn(b'<h1>All Users</h1>', response.data)

self.assertNotIn(b'<p>No users!</p>', response.data)

self.assertIn(b'testname1', response.data)

self.assertIn(b'testname2', response.data)

Убедимся, что тест не работает, а затем обновим функцию-представле-

ние:

@users_blueprint.route('/', methods=['GET'])

def index():

users = User.query.all()

return render_template('index.html', users=users)

Теперь тест должен успешно выполниться.

Пользователи должны иметь возможность добавить нового пользователя,

отправив на сервер форму, которая затем добавит пользователя в базу данных.

Снова начнём с написания теста:

def test_main_add_user(self):

"""Проверка, что в базу данных можно добавить нового пользовате-

ля."""

with self.client:

response = self.client.post( '/',

data=dict(username='testname1',

email='testname1@soflaskapp.com'), \ follow_redirects=True)

self.assertEqual(response.status_code, 200)

self.assertIn(b'<h1>All Users</h1>', response.data)

self.assertNotIn(b'<p>No users!</p>', response.data)

self.assertIn(b'testname1', response.data)

Затем обновим функцию представления:

@users_blueprint.route('/', methods=['GET', 'POST'])

def index():

if request.method == 'POST':

31

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]