Flask для розробки додатка електронної комерції

pic

У цій статті ми крок за кроком розглянемо, як розробити сучасний додаток для електронної комерції, використовуючи Flask. (Проект вимагає базових знань кодування)

Flask — це легкий і гнучкий фреймворк, розроблений мовою Python. У нашому додатку ми використаємо Flask як фреймворк, SQLAlchemy для роботи з базою даних та Flask Migration для керування міграціями бази даних.

Розпочнемо проект зі створення бази даних. У цій статті ми використовуватимемо наступну схему бази даних. Як створити базу даних для проекту ми описали в статті Управління базою даних для E-Commerce проекту за допомогою MYSQL.

pic

Ми створимо наш проект, використовуючи цю схему. Тепер, коли база даних готова, можемо розпочати налаштування Flask. Відкриваємо термінал у нашому Python компіляторі. Напишемо ‘ pip install flask ’, щоб встановити Flask в наш додаток. Потім, написавши ‘ pip install flask-sqlalchemy ’, встановимо SQLAlchemy для нашого проекту. SQLAlchemy дозволяє працювати з базою даних через Python об'єкти, даючи змогу виконувати операції з базою без написання SQL-запитів. Це популярна ORM (Object-Relational Mapping) бібліотека. Тепер для полегшення управління міграціями бази даних напишемо ‘ pip install flask-migrate ’ і встановимо бібліотеку для міграцій. Ця бібліотека є розширенням Flask, яке використовується для створення та управління схемами бази даних. Flask-Migrate працює разом з SQLAlchemy та використовує бібліотеку Alembic для відслідковування та застосування змін у базі даних. Це дозволяє нам зручно керувати змінами в схемі бази даних під час розробки додатку.

На даному етапі ми завершили необхідні налаштування. Тепер можемо розпочати налаштування архітектури проекту та класів додатку. Для цього в проекті ми будемо використовувати моделі, сервіси та API шари. Кожен із цих шарів має свої функціональні блоки. Створимо ці шари в пакеті з ім'ям app.

pic

Тепер давайте у головному файлі (серверному файлі) створимо файли app.py та config.py. Файл app буде точкою старту нашого додатку, а config міститиме деякі налаштування для додатку.

pic

Наш проект на даному етапі готовий до основи. Тепер давайте у файлі app (ініціалізація) додамо функцію для запуску додатку.

pic

Ми написали код для запуску додатку, тепер давайте налаштуємо файл config.

pic

У файлі config ми створили наступний клас. В цьому класі містяться налаштування URI для підключення до бази даних та інші налаштування. Тут SQLAlchemy містить систему для відстеження змін у моделях вашого додатку. Ця система відслідковує кожну зміну моделі та надає нам інформацію, коли це необхідно. Однак, ця функція зазвичай є непотрібною і може спричинити зайве споживання ресурсів. Тому ми вимикаємо її за допомогою коду ‘ SQLALCHEMYTRACKMODIFICATIONS = False ’. Тепер давайте подивимось на налаштування DATABASEURI. Тут ми вказуємо наше ім’я користувача та пароль для бази даних. Якщо ми працюємо локально, то значення має бути _‘ localhost:3306 ’. Для підключення до MySQL нам потрібно використати бібліотеку pymysql. Додаємо її в проект за допомогою ‘ pip install pymysql ’. Тепер, коли файл config налаштований, повертаємось до файлу ініціалізації.
(app — > init)

pic

З новим кодом, який ми написали вище, ми повідомляємо Flask, що конфігураційний файл для нашого додатку — це файл Config. Тепер давайте визначимо міграцію та SQLAlchemy у нашому проекті.

pic

Після початкових налаштувань у функції create_app ми інтегруємо міграцію та SQLAlchemy в наш проект. На цьому етапі наша робота завершена. Тепер можемо перейти до файлу app і показати, що наш додаток буде працювати з цим файлом.

pic

Процес завершено. Тепер, коли наш додаток готовий, потрібно підключити базу даних через міграції. Для цього ми виконаємо наступні команди:

flask db init (створює файли міграцій для проекту)

flask db stamp head (вважає поточну базу даних початковим станом)

Тепер, коли ми виконали ці команди, заклали основу для нашого проекту. Тепер можемо розпочати створення наших шарів. Спочатку давайте почнемо з моделі. В цьому шарі ми будемо визначати класи, які представлятимуть наші таблиці в базі даних. Почнемо з написання класу моделі для таблиці користувачів.

pic

Спочатку ми визначаємо клас як модель за допомогою коду db.Model. Далі ми вказуємо, яка таблиця в базі даних буде відповідати цьому класу, написавши __tablename_ = “users”. Після того як визначили таблицю, можемо додавати колонки. Для визначення колонок ми використовуємо _db.Column. Потім вказуємо, яка колонка і з яким типом даних буде представлятися. Важливою деталею є те, що ми не створюємо колонку для хешу пароля тут, тому що зберігати пароль безпосередньо в моделі користувача є неправильним. Це буде розглянуто пізніше в статті. Тепер ми створили модель для таблиці users. Тепер переходимо до моделі для таблиці addresses:

pic

Тут ми бачимо новий код. Колонка userid є зовнішнім ключем, тому ми позначаємо її за допомогою _db.ForeignKey, після чого вказуємо, до якої таблиці та колонки вона відноситься. Тепер Flask буде знати, що колонка userid в таблиці addresses є посиланням на колонку userid в таблиці users. Тепер давайте створимо моделі для таблиць categories і products.

pic

pic

Тут ми майже все вивчили. Окрім цього, в таблиці products ми використовуємо onupdate для визначення дії, яка буде виконана при оновленні. Тепер давайте створимо модель для таблиці orders.

pic

Тут ми визначаємо колонку з типом даних enum. Спочатку ми створюємо клас enum, що містить значення OrderStatus. Потім в колонці ми використовуємо db.Enum для посилання на цей клас enum. За замовчуванням значення буде ‘Pending’ з класу OrderStatus. Нарешті, давайте визначимо нашу таблицю зв'язку.

pic

Тепер, коли ми написали всі моделі, у нас не залишилося незрозумілих моментів.

Тепер, щоб перетворити наші класи моделей з Python об'єктів на типи словників, ми будемо використовувати бібліотеку для серіалізації. Це процес, який називається serialization. Детальніше про це ми поговоримо пізніше.
Для виконання цього перетворення давайте встановимо необхідні бібліотеки.

pip install flask-marshmallow _(використовується для перетворення класів моделей на словники)_
pip install marshmallow-sqlalchemy _(необхідна бібліотека для інтеграції Marshmallow з SQLAlchemy)_

pic

За допомогою позначених рядків ми інтегрували бібліотеку Marshmallow в наш проект. Тепер перейдемо до написання класів, які будуть перетворювати наші моделі на словники.

pic

pic

У цих класах ми визначили схеми. За допомогою model = ми вказуємо, до якої моделі відноситься схема. Параметр loadinstance = True_ дозволяє безпосередньо перетворювати дані зі словника на модель. Крім того, якщо в моделі є зовнішні ключі, ми використовуємо параметр includefk = True_, що дозволяє включити зовнішні ключі до словника. Те саме ми зробили і для інших класів моделей.

Тепер, коли наші моделі готові, можемо перейти до написання класу для шару сервісів. Почнемо з написання сервісу для користувачів.

pic

Тут ми написали перший метод. Ми позначили його як ‘@staticmethod’, що дозволяє викликати цей метод без створення об'єкта класу, безпосередньо через клас. Використовуючи модель User, ми робимо запит через query і за допомогою all() отримуємо всі записи. Потім ми використовуємо метод dump з нашою схемою для перетворення даних у словник і повертаємо результат. Параметр many=True важливий, оскільки, якщо ми відправляємо список на перетворення, цей параметр дозволяє працювати з колекцією. Тепер давайте напишемо ще один метод.

pic

Цей метод приймає параметр userid, шукає запис за допомогою методу _filterby, а оскільки цей метод повертає список, ми беремо перший елемент з нього за допомогою _first(). Оскільки ми знаємо, що запит поверне лише один елемент (userid — унікальний стовпець), ми використовуємо _first(). Однак запис може не бути знайдений, тому ми додаємо перевірку if not user, щоб обробити помилку, якщо такого користувача не існує. Якщо користувач знайдений, ми перетворюємо його на словник і повертаємо результат (ми не використовуємо many=True, оскільки повертається тільки один запис). Модель користувача наразі готова. Ми ще повернемося до інших запитів щодо користувачів пізніше.

Тепер переходимо до написання сервісу для адрес:

pic

pic

pic

Тепер давайте розглянемо два нових методи — add і deletebyid. У методі add нам передають дані адреси у форматі JSON. За допомогою схеми ми можемо перетворити ці дані на об'єкт адреси. Для цього використовуємо функцію load(). Якщо під час перетворення будуть помилки валідації (наприклад, пропущені або неправильно написані поля), ми отримаємо помилку ValidationError, яку обробляємо через блок try-except. Якщо помилка не виникне, ми підключимося до бази даних через db.session і додамо дані до бази за допомогою add(), а потім застосуємо зміни через commit(). Якщо ми не викликаємо commit(), зміни не будуть збережені в базі даних.
Наприкінці, для позначення того, що операція додавання завершена, ми повертаємо повідомлення. У методі deletebyid після того, як ми знаходимо запис, ми видаляємо його за допомогою delete(). У методі update ми спочатку знаходимо запис, що відповідає id, наданому в JSON. Потім ми оновлюємо відповідні поля, використовуючи значення з JSON. Якщо поле в JSON існує у моделі address, ми оновлюємо його через метод setattr(). Оскільки колонка addressid не повинна змінюватися, ми пропускаємо її, використовуючи перевірку _key != ‘addressid’. Після цього ми викликаємо _commit(), щоб зберегти зміни в таблиці. Подібним чином ми заповнюємо інші методи в сервісах. Залежно від потреб проекту методи можуть змінюватися. Ви можете додати більше обробки помилок. Тут ми описали все просто і коротко. Тепер, коли наші сервіси завершені, можемо переходити до шару API.

Тепер давайте почнемо з створення файлу API для користувача.

pic

Спочатку ми визначаємо шаблон userbp. Цей шаблон міститиме всі шляхи для наших endpoint. Після того, як ми створили userbp, ми вказуємо ім'я файлу як параметр name. Далі, для кожного методу, ми будемо використовувати ‘@userbp.route’, щоб налаштувати шлях для кожного endpoint. Шлях виглядає так: _http://127.0.0.1:5000/

Кожна функція має на меті повернути дані з сервісного шару через відповідний endpoint. Після повернення даних ми також відправляємо статус 200, що означає успішний GET запит. Ось деякі значення статусів:

200 OK → Запит був успішно оброблений і клієнту повернуто корисну відповідь.
201 Created → Новий ресурс успішно створений (зазвичай для операцій типу POST).
204 No Content → Запит успішно оброблений, але вмісту для повернення немає.

🚫 400 Bad Request → Запит клієнта містить помилки або відсутні параметри.
🚫 401 Unauthorized → Не вдалося пройти автентифікацію або дані неповні.
🚫 403 Forbidden → У користувача немає доступу до зазначеного ресурсу.
🚫 404 Not Found → Вказаний ресурс не знайдений або не існує.
🚫 405 Method Not Allowed → Клієнт намагається використати недозволений HTTP метод (GET, POST, DELETE тощо)._

⚠️ 500 Internal Server Error → Сталася непередбачена помилка на сервері.
⚠️ 503 Service Unavailable → Сервер тимчасово недоступний (наприклад, через обслуговування або перевантаження).

Ви можете використовувати ці коди відповідно до вимог ваших методів. На даному етапі ми використовуємо лише базовий статус 200 OK. Давайте подивимося на наступний метод, де ми зазначили, що запит потребує параметра id. Шлях виглядає наступним чином: http://127.0.0.1:5000/id?id=1. Параметр id передається після знака питання, і значення 1 потрапляє в змінну userid в методі, що передає його до сервісу. Важливою частиною є метод _jsonify(), який перетворює словник з сервісу в JSON формат і повертає його.

Тепер давайте створимо файл API для адрес:

pic

У файлі Address API ми додамо три методи, які описані вище. Першим з них буде метод getjson(), який дозволяє запитувати дані у форматі JSON. Ми передаємо ці дані до сервісу. Іншим важливим моментом є частина _methods=['POST'], де ми вказуємо, що цей метод не є методом GET за замовчуванням, а має працювати як POST.
Загалом, наші HTTP методи виглядають наступним чином:

GET → Використовується для отримання даних з сервера, не змінюючи дані.

POST → Використовується для додавання нового ресурсу на сервер.

PUT → Використовується для повного оновлення наявного ресурсу.

PATCH → Використовується для оновлення тільки певних полів наявного ресурсу.

DELETE → Використовується для видалення вказаного ресурсу з сервера.

HEAD → Виконує ту ж саму операцію, що й GET, але повертає тільки заголовки (header), без тіла відповіді.

OPTIONS → Використовується для перевірки, які HTTP методи підтримуються сервером.

Ці методи можна використовувати в залежності від потреб і вимог проекту. Тепер, коли ми завершили це, ви можете писати інші API класи схожим чином. Нарешті, нам потрібно інтегрувати шаблони, які ми написали як Blueprint, в наш додаток. Для цього ми додаємо наступні рядки до файлу додатку.

pic

За допомогою register_blueprint() ми інтегруємо наш шаблон в додаток. Потім ми визначаємо URL префікс, наприклад, ‘/user’. Завдяки цьому, всі endpoint в API для користувача будуть мати префікс ‘/user’. Після того, як це буде зроблено, наш проект буде готовий до запуску.

Це був кінець нашої статті. З тими знаннями, які ви отримали, тепер ви можете основно написати бекенд частину e-commerce проекту. Більш того, з тим, що ви дізналися про Flask, ви зможете розробляти й інші проекти. Дякуємо, що читали!

Перекладено з: Flask ile E-Ticaret Uygulaması

Leave a Reply

Your email address will not be published. Required fields are marked *