AIOgram3 5.1. Создание структуры
Большинство проектов не ограничиваются одним лишь файлом
Создадим основной пакет
Если, вы работаете в PyCharm или другой Python-направленной IDE, то достаточно в контекстном меню директории выбрать "New - Python Package".
Но создать пакет можно и вручную.
Для этого необходимо создать директорию с необходимым именем пакета. Внутри директории создать пустой файл
При каждом создании пакета, необходимо создавать внутри пустой файл __init__.py
Большинство проектов не ограничиваются одним лишь файлом
main.py, напротив, часто проекты состоят из множества файлов с кодом конкретной логики. Для этого в Python предусмотрена "пакетная" система. Пакет является директорией, которая содержит в себе модули и подпакеты. Он позволяет логически объединять связанный функционал и предоставляет простой способ управления зависимостями и кодом в рамках проекта.Создадим основной пакет
botlogic со всей будущей логикой.Если, вы работаете в PyCharm или другой Python-направленной IDE, то достаточно в контекстном меню директории выбрать "New - Python Package".
Но создать пакет можно и вручную.
Для этого необходимо создать директорию с необходимым именем пакета. Внутри директории создать пустой файл
__init__.py. Данный файл сообщит интерпретатору, что директория является пакетом.При каждом создании пакета, необходимо создавать внутри пустой файл __init__.py
👍3
В этом пакете создадим файл
В этом файле будут располагаться, при необходимости, настройки бота. Пока, что мы перенесём в него токен бота и добавим ID администратора.
Тут, для удобства применим ООП.
Те, кто уже успели испугаться, расслабьтесь, в создании бота ООП либо крайне мало, либо нет вовсе. Тут я применяю его банально для удобства.
Создадим дата-класс
Мы создали класс
- Строковое
- Целочисленное
Далее должно было быть несколько методов, таких как
Декоратор
Когда применяется декоратор
1.
2.
И ряда других.
Кроме того, декоратор
Продолжение в следующем посте.
Файлы к посту, можно получить в боте по коду: 488659
Пост на сайте.
Поддержать канал.
#aiogram #python #python_package #структура #dataclass
settings.py.В этом файле будут располагаться, при необходимости, настройки бота. Пока, что мы перенесём в него токен бота и добавим ID администратора.
Тут, для удобства применим ООП.
Те, кто уже успели испугаться, расслабьтесь, в создании бота ООП либо крайне мало, либо нет вовсе. Тут я применяю его банально для удобства.
Создадим дата-класс
Secrets и в нём два поля token и admin_id:from dataclasses import dataclassРазберём, что тут происходит.
@dataclass
class Secrets:
token: str = 'ваш_токен'
admin_id: int = 12345
Мы создали класс
Secrets и определили два поля:- Строковое
token в котором указываем полученный от BotFather токен бота.- Целочисленное
admin_id в котором необходимо указать ваш Telegram-ID, но это будет несколькими постами далее, пока просто заполните любым числом.Далее должно было быть несколько методов, таких как
__init__ и геттеры полей, но нам тут всё это не нужно. Для избегания большого количества кода, мы используем декоратор @dataclass.Декоратор
@dataclass - позволяет автоматически сгенерировать методы класса для работы с данными.Когда применяется декоратор
@dataclass к классу, он автоматически добавляет реализацию необходимых методов, таких как:1.
__init__: Создает конструктор класса, принимающий значения для каждого атрибута.2.
__repr__: Создает строковое представление объекта, которое используется при вызове repr().И ряда других.
Кроме того, декоратор
@dataclass позволяет использовать аннотации типов для объявления типов полей класса, что упрощает чтение кода.Продолжение в следующем посте.
Файлы к посту, можно получить в боте по коду: 488659
Пост на сайте.
Поддержать канал.
#aiogram #python #python_package #структура #dataclass
👍4
AIOgram3 5.2. Создание структуры, продолжение
Не уходя из файла
Перенесём сюда инициализацию бота, а именно строку и сразу заменим содержимое на получение данных из класса
Таким образом, мы сможем обращаться к экземпляру бота не только из главного файла.
С файлом
Перейдём в файл
Было:
Поменяем на:
Не уходя из файла
settings.pyПеренесём сюда инициализацию бота, а именно строку и сразу заменим содержимое на получение данных из класса
Secrets:from aiogram import Bot
bot = Bot(token=Secrets.token)
Таким образом, мы сможем обращаться к экземпляру бота не только из главного файла.
С файлом
settings.py мы пока закончили. Перейдём в файл
main.py и изменим импорты.Было:
from aiogram import Bot, Dispatcher
Поменяем на:
from aiogram import Dispatcher
from botlogic.settings import bot
👍4
Как вы помните, при запуске бота, не понятно, запустился он или нет, поскольку в терминале не было никаких данных. Давайте это исправим, добавив базовый логгер.
Перед переменной dp добавляем пустую строку и вставляем туда код логгера, а в начло файла добавляем строку импорта:
-
-
С уровнем логирования всё понятно, он будет выводить данные уровня
Строка лога состоит из 7ми переменных:
-
-
-
-
-
-
-
В следующем посте, продолжим формировать структуру и сделаем оповещение администратора о запуске или остановке бота.
Файлы к посту, можно получить в боте по коду: 488659
Пост на сайте.
Поддержать канал.
#aiogram #python #python_package #структура #logging
Перед переменной dp добавляем пустую строку и вставляем туда код логгера, а в начло файла добавляем строку импорта:
import loggingПри запуске бота, будет инициализироваться метод
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s - [%(levelname)s] - %(name)s - (%(filename)s).%(funcName)s(%(lineno)d) - %(message)s"
)
basicConfig из втроенной библиотеки logging. В него мы передаём два параметра:-
level - определяющий уровень выводимой информации. Основные уровни информирования: DEBUG, INFO, WARNING, ERROR.-
format - определяющий формат выводимой информации.С уровнем логирования всё понятно, он будет выводить данные уровня
INFO, то о переменных в формате стоит рассказать подробнее.Строка лога состоит из 7ми переменных:
-
%(asctime)s — заменяется на текущее время в формате "год-месяц-день час:минута:секунда";-
%(levelname)s — заменяется на уровень важности лога, в нашем случае INFO;-
%(name)s — заменяется на имя логгера, который записывает сообщение;-
%(filename)s — заменяется на имя файла, в котором была вызвана функция логирования;-
%(funcName)s — заменяется на имя функции, в которой была вызвана функция логирования;-
%(lineno)d — заменяется на номер строки, в которой была вызвана функция логирования;-
%(message)s — заменяется на текст сообщения, переданного для записи в лог.В следующем посте, продолжим формировать структуру и сделаем оповещение администратора о запуске или остановке бота.
Файлы к посту, можно получить в боте по коду: 488659
Пост на сайте.
Поддержать канал.
#aiogram #python #python_package #структура #logging
👍5
AIOgram3 6. Информирование администратора
Теперь давайте добавим функционал информирование админа бота о его запуске или остановке.
Перейдём в файл
В пакете
Напоминаю, что пакет можно создать средствами IDE, выбрав создать новый Python Package или создать вручную, создав директорию и в ней пустой файл __init__.py.
В нём у нас будут находится обработчики сообщений пользователей, команд или различных событий.
В пакете
Теперь давайте добавим функционал информирование админа бота о его запуске или остановке.
Перейдём в файл
settings.py и в поле admin_id в классе Secrets пропишем ваш Telegram-ID. Получить его можно у бота https://t.iss.one/getmyid_botВ пакете
botlogic создадим новый пакет handlers. Напоминаю, что пакет можно создать средствами IDE, выбрав создать новый Python Package или создать вручную, создав директорию и в ней пустой файл __init__.py.
В нём у нас будут находится обработчики сообщений пользователей, команд или различных событий.
В пакете
handlers создадим файл events.py. В данном файле, будут находиться обработчики событий. Сейчас мы напишем два обработчика реагирующих на событие запуска и остановки бота.from botlogic.settings import bot, Secrets
async def start_bot():
await bot.send_message(Secrets.admin_id, 'Бот запущен')
async def stop_bot():
await bot.send_message(Secrets.admin_id, 'Бот остановлен')
👍3
Мы создали две асинхронные функции
Однако, вот так оставлять текст в функции не правильно. В случае, если надо будет изменить текст, в его поисках придётся перелопатить часть файлов бота. По этому, давайте создадим единый файл, в котором будем хранить все текстовые сообщения.
В пакете
И создадим две функции
Переходим в файл
Запустим бота и убедимся, что уведомления приходят, а в терминале появился лог событий.
Файлы к посту, можно получить в боте по коду: 270319
Пост на сайте.
Поддержать канал.
#aiogram #python
start_bot и stop_bot. В теле функции вызвали метод send_message из экземпляра класса Bot. В метод первым параметром передаётся Telegram-ID получателя, а вторым текст сообщения. Однако, вот так оставлять текст в функции не правильно. В случае, если надо будет изменить текст, в его поисках придётся перелопатить часть файлов бота. По этому, давайте создадим единый файл, в котором будем хранить все текстовые сообщения.
В пакете
botlogic создадим файл views.py.И создадим две функции
start_bot_msg и start_bot_msg:def start_bot_msg():Две простейшие функции, возвращающее текст при вызове. Изменим наши функции в файле
return 'Бот запущен'
def stop_bot_msg():
return 'Бот остановлен'
events.py, что бы они получали строки из только что созданных функций:from botlogic.settings import bot, SecretsОсталось только зарегистрировать данные события.
from botlogic.views import start_bot_msg, stop_bot_msg
async def start_bot():
await bot.send_message(Secrets.admin_id, start_bot_msg())
async def stop_bot():
await bot.send_message(Secrets.admin_id, stop_bot_msg())
Переходим в файл
main.py и в функции start(), под вызовом диспетчера прописываем следующие строки:from botlogic.handlers.events import start_bot, stop_botЭто встроенные методы диспетчера. Зарегистрировав события, когда в блоке
dp.startup.register(start_bot)
dp.shutdown.register(stop_bot)
try-finally запустится бот, он автоматически вызовет нашу функцию start_bot() и мы получим уведомление от бота. С остановкой бота аналогично.Запустим бота и убедимся, что уведомления приходят, а в терминале появился лог событий.
Файлы к посту, можно получить в боте по коду: 270319
Пост на сайте.
Поддержать канал.
#aiogram #python
👍3
Django 8. Первая модель
Для постов на сайте и бота выдающего архив с дополнительными материалами, нужен удобный способ хранения файлов. Для этого будем использовать модель в Django.
В Django модель - это класс, который определяет структуру и поведение данных в вашем приложении. Он представляет таблицу в базе данных, где каждое поле в модели соответствует столбцу в таблице.
Давайте создадим первую модель, которая в последствии будет расширена.
Откроем файл
Для постов на сайте и бота выдающего архив с дополнительными материалами, нужен удобный способ хранения файлов. Для этого будем использовать модель в Django.
В Django модель - это класс, который определяет структуру и поведение данных в вашем приложении. Он представляет таблицу в базе данных, где каждое поле в модели соответствует столбцу в таблице.
Давайте создадим первую модель, которая в последствии будет расширена.
Откроем файл
models.py в директории приложения и напишем класс PostFilesModel.👍2
class PostFilesModel(models.Model):Разберём написанное:
title = models.CharField(max_length=200,
verbose_name='Имя файла')
file = models.FileField(upload_to='post_files/')
code = models.IntegerField(default=0,
verbose_name='Код файла',
unique=True)
download_count = models.IntegerField(default=0,
verbose_name='Скачиваний')
class Meta:
verbose_name = 'Файл поста'
verbose_name_plural = 'Файлы постов'
def increment_download_count(self):
self.download_count += 1
self.save()
def __str__(self):
return self.title
Мы создали класс
PostFilesModel и унаследовали его от встроенного в Django класса Model.В нём мы прописали четыре поля:
-
title - поле типа CharField. В нём хранятся строки. Мы в него будем передавать имя файла. В параметрах поля определена максимальная длина max_length в 200 символов и передали имя поля verbose_name.-
file - поле типа FileField. Представляет собой возможность загружать файлы на сервер. В нём мы указали параметр upload_to указывающий куда будет загружаться файл. Это не полный путь! Все файлы будут загружаться в папку media, а указанный выше путь, это путь внутри папки media. -
code - поле типа IntegerField. В нём хранятся целочисленные значения. В данное поле будет прописываться цифровой код, по которому можно будет получить файл у бота.-
download_count - поле типа IntegerField. В нём будет вестись статистика по скачиваниям файла. Кроме упомянутого ранее параметра определяющего имя поля, также был передан параметр default, обозначающий значение по умолчанию для создаваемого объекта модели.Далее создали внутренний класс
Meta. В этом классе настраиваются различные параметры модели, такие как сортировка, указание на конкретную таблицу в БД, имя модели и множество других.В нашем случае, мы передаём два параметра: Имя и Множественное имя модели.
Ниже определён метод
increment_download_count. Данный метод при вызове будет увеличивать счётчик загрузок на единицу.И последний метод представляет переопределение метода
__str__, возвращающего текстового представления поля title.Применим изменения вызвав создание миграций и саму миграцию, выполнив две команды в терминале:
python manage.py makemigrationsВ следующем посте добавим модель в панель администратора и протестируем.
python manage.py migrate
Файлы к посту, можно получить в боте по коду: 225028
Пост на сайте.
Поддержать канал.
#django #python #модели #миграции
👍3
Django 9. Регистрация модели
Для того, что бы можно было взаимодействовать с моделью, а именно добавлять, изменять или редактировать объекты из панели администратора, необходимо модель там зарегистрировать.
Откроем файл
И пропишем там три поля:
-
-
-
Для того, что бы можно было взаимодействовать с моделью, а именно добавлять, изменять или редактировать объекты из панели администратора, необходимо модель там зарегистрировать.
Откроем файл
admin.py в директории приложения и создадим класс PostFilesAdmin унаследованный от Django-класса ModelAdmin.И пропишем там три поля:
-
list_display - со списком полей модели, значения которых необходимо отображать на странице модели. В нашем случае, это поля - название, код и количество загрузок.-
search_fields - определяет, по каким полям в модели будет происходить поиск.-
exclude - определяет поля, которые необходимо скрыть при создании объекта модели. В нашем случае это поле с количеством скачиваний. Поскольку оно всегда начинается с 0, то и переопределять нет необходимости.Модель описали, теперь надо её зарегистрировать. Это можно сделать двумя способами:
1. В конце файла прописать
2. С помощью декоратора
Субъективно, мне больше нравится второй вариант.
Код:
Запустим Django командой
В списке должен появиться блок
Нажмём на
Нажмём "Добавить" в меню слева или кнопку "Добавить файл поста" в правой части экрана.
В открывшемся окне будет всего два поля, первое название, а второе файл для загрузки. Попробуйте, что-то написать и прикрепить. После чего нажмите "Сохранить".
После сохранения, нас перебрасывает обратно к списку записей и сверху есть плашка с сообщением "Файл поста "Тестовый файл" был успешно добавлен.".
Вернёмся в IDE и в диспетчере файлов увидим, что в корне проекта появилась папка
И если мы в адресной строке прямо пропишем путь к файлу:
Файлы загружаются и отдаются пользователю по пути их расположения.
В следующем посте начнём делать API для передачи данных файлов, а вернее их локального пути для Telegram-бота
Файлы к посту, можно получить в боте по коду: 387443
Пост на сайте.
Поддержать канал.
#django #python #модели #админка #admin
1. В конце файла прописать
admin.site.register(models.PostFilesModel, PostFilesAdmin). Где первым параметром передаётся модель из файла models.py, а вторым написанный выше класс для этой модели.2. С помощью декоратора
@admin.register(models.PostFilesModel). В параметр которого передаём необходимую модель.Субъективно, мне больше нравится второй вариант.
Код:
from django.contrib import adminМодель зарегистрирована, давайте проверим её работу.
from . import models
@admin.register(models.PostFilesModel)
class PostFilesAdmin(admin.ModelAdmin):
list_display = ('title', 'download_count')
search_fields = ['title', ]
exclude = ['download_count', ]
Запустим Django командой
python manage.py runserver и перейдём в панель администратора.В списке должен появиться блок
BLOG с единственным пунктом Файлы постов.Нажмём на
Файлы постов и попадём на страницу со списком записей. Пока что тут пусто. Нажмём "Добавить" в меню слева или кнопку "Добавить файл поста" в правой части экрана.
В открывшемся окне будет всего два поля, первое название, а второе файл для загрузки. Попробуйте, что-то написать и прикрепить. После чего нажмите "Сохранить".
После сохранения, нас перебрасывает обратно к списку записей и сверху есть плашка с сообщением "Файл поста "Тестовый файл" был успешно добавлен.".
Вернёмся в IDE и в диспетчере файлов увидим, что в корне проекта появилась папка
media, а в ней post_files и отправленный ранее файл.И если мы в адресной строке прямо пропишем путь к файлу:
https://127.0.0.1:8000/media/post_files/ваш_файл_включая_расширение, то файл начнёт скачиваться! А по такому-же пути в адресе https://pressanybutton.ru, но с файлом 68.zip будет архивчик с картинками 😉Файлы загружаются и отдаются пользователю по пути их расположения.
В следующем посте начнём делать API для передачи данных файлов, а вернее их локального пути для Telegram-бота
Файлы к посту, можно получить в боте по коду: 387443
Пост на сайте.
Поддержать канал.
#django #python #модели #админка #admin
🔥3
Приветствую.
Каналу уже три недели.
За это время на канал подписалось 78 человек!
Посты выходят или каждый день или несколько в день.
В скором времени будет бот, с файлами к постам.
Будет сделан сайт, где можно будет почитать те же посты, но в более удобном формате и со скриншотами.
В ближайшие две недели, выйдет много постов по Django и Aiogram. Доделаем бота и начнём делать блог на сайте.
Я очень надеюсь, что вам нравится, что я делаю. По этому прошу, рассказать о канале друзьям или людям, кому это тоже может быть интересно.
Ещё, хотелось бы видеть больше обратной связи по материалам.
Достаточно ли понятно написано? Нужно ли делать более длинные? И другие возникающие у вас вопросы.
Спасибо вам, за то, что читаете.
Каналу уже три недели.
За это время на канал подписалось 78 человек!
Посты выходят или каждый день или несколько в день.
В скором времени будет бот, с файлами к постам.
Будет сделан сайт, где можно будет почитать те же посты, но в более удобном формате и со скриншотами.
В ближайшие две недели, выйдет много постов по Django и Aiogram. Доделаем бота и начнём делать блог на сайте.
Я очень надеюсь, что вам нравится, что я делаю. По этому прошу, рассказать о канале друзьям или людям, кому это тоже может быть интересно.
Ещё, хотелось бы видеть больше обратной связи по материалам.
Достаточно ли понятно написано? Нужно ли делать более длинные? И другие возникающие у вас вопросы.
Спасибо вам, за то, что читаете.
🔥8
Django 10. Пишем API - Сериализатор
С места в карьер! Там где все обычно пишут модели, представления и странички для блога, я же предлагаю окунуться сразу в нечто более полезное, а именно решить поставленную задачу.
Суть задачи в следующем: Необходимо, что бы Telegram-бот обращался к Django по определённому адресу, передавая цифровой код, а в ответ получал расположение файла на сервере и собственно отправлял этот файл пользователю. Этим и займёмся в ближайшие несколько постов, а потом уже можно будет отдохнуть за созданием сайта.
Первым делом необходимо установить библиотеку
После этого, в директории приложения создадим два файла:
В файле
С места в карьер! Там где все обычно пишут модели, представления и странички для блога, я же предлагаю окунуться сразу в нечто более полезное, а именно решить поставленную задачу.
Суть задачи в следующем: Необходимо, что бы Telegram-бот обращался к Django по определённому адресу, передавая цифровой код, а в ответ получал расположение файла на сервере и собственно отправлял этот файл пользователю. Этим и займёмся в ближайшие несколько постов, а потом уже можно будет отдохнуть за созданием сайта.
Первым делом необходимо установить библиотеку
djangorestframework командой pip install djangorestframework и добавить установленную версию в requirements.txt.После этого, в директории приложения создадим два файла:
api.py и serializers.py.В файле
api.py будем писать обработчики запросов, а в файле serializers.py будет происходить сериализация из данных объекта модели в JSON.Начинать можно как с сериализатора, так и с обработчика. Но я всё таки рекомендую начинать с сериализатора, так можно сразу определиться с тем, какие данные нам нужно возвращать.
Перейдём в файл
В нашей модели нет поля
Затем создадим класс
Поскольку поле
Код:
В следующем посте напишем обработчик
Файлы к посту, можно получить в боте по коду: 462013
Пост на сайте.
Поддержать канал.
#django #python #api #serializer #сериализатор #модель
Перейдём в файл
serializers.py и создадим класс FileModelSerializer унаследованный от Django REST ModelSerializer.В нашей модели нет поля
path, хранящего путь на сервере до файла, но есть метод для получения такого пути. Но так как сериализатор работает именно с полями модели, а не их методами, создадим новое поле для сериализатора file_path и сделаем его экземпляром класса SerializerMethodField.Затем создадим класс
Meta, на подобии того, что мы делали в модели. Определим в нём поле model и fields. В поле model передадим нашу модель файла, а в поле fields, укажем те поля модели, которые хотим получить, присвоив ему список нужных полей. Нам достаточно поля title и ранее созданного поля file_path.Поскольку поле
file_path у нас создано только для сериализатора, необходимо его заполнить данными. Создадим статический метод get_file_path передавая в атрибуты obj, то есть наш объект модели. В этом методе сделаем возврат пути к файлу или None, если пути нет.Код:
from rest_framework import serializersТаким образом, обратившись к сериализатору
from . import models
class FileModelSerializer(serializers.ModelSerializer):
file_path = serializers.SerializerMethodField()
class Meta:
model = models.PostFilesModel
fields = ['title', 'file_path']
@staticmethod
def get_file_path(obj):
return obj.file.path if obj.file else None
FileModelSerializer, и передав в него объект модели PostFilesModel, мы получим данные из двух полей "Название" и "Путь к файлу". А если мы применим к классу метод .data, то в ответ нам вернётся JSON объект.В следующем посте напишем обработчик
GET запроса для нашего API.Файлы к посту, можно получить в боте по коду: 462013
Пост на сайте.
Поддержать канал.
#django #python #api #serializer #сериализатор #модель
Django 11. Пишем API - Обработчик запросов
Продолжим предыдущий пост и напишем обработчик запросов.
Перейдём в файл
Создадим класс
Мы будем обрабатывать
Можно создавать не только
В запросе, мы будем использовать
Например
Продолжим предыдущий пост и напишем обработчик запросов.
Перейдём в файл
api.py. Создадим класс
GetFilePath наследуемый от APIView. Мы будем обрабатывать
GET запрос, то есть бот отправит запрос на получение данных, поэтому создадим в классе статический метод get принимающий в качестве атрибута request - HTTP-запрос.Можно создавать не только
GET, но и POST, PUT, DELETE и другие типы HTTP-запросов.В запросе, мы будем использовать
query-параметры. Они передаются вместе с запросом добавляя в URL-адрес символ вопроса ? и перечисление именованных переменных, разделённых между собой знаком амперсанда &.Например
https://pressanybutton.ru/?code=123, где code параметр, а 123 его значение.Создадим переменную
Во избежание ошибок, если вдруг пользователь введёт не существующий код файла, обернём дальнейший код в
Внутри блока
Успешно получив объект файла, вызовем его метод для увеличения числа загрузок.
Далее создадим переменную
Обработав все данные можно возвращать пользователю ответ, передав в качестве ответа JSON представление сериализованных данных.
В случае если, объект по запрошенному коду не найден, провалившись в блок except, мы сразу делаем возврат пустого значения пользователю со статус-кодом
Код обработчика:
Перейдём в файл
В новой переменной, определим список и добавим в него переменную объект паттерна.
В следующем посте начнём писать функционал бота по запросу и отправке файла.
Файлы к посту, можно получить в боте по коду: 586344
Пост на сайте.
Поддержать канал.
#django #python #api #view #представление #запросы #get
code в которую будем получать из запроса значение одноимённого параметра.Во избежание ошибок, если вдруг пользователь введёт не существующий код файла, обернём дальнейший код в
try-except.Внутри блока
try создадим переменную file, в которую получим объект модели с совпадающим кодом. Если объект не будет найден, то дальнейший код не сработает и нас выбросит на обработку исключения, о ней чуть позже.Успешно получив объект файла, вызовем его метод для увеличения числа загрузок.
Далее создадим переменную
serialized_data в которую будет записан объект сериализованных данных.Обработав все данные можно возвращать пользователю ответ, передав в качестве ответа JSON представление сериализованных данных.
В случае если, объект по запрошенному коду не найден, провалившись в блок except, мы сразу делаем возврат пустого значения пользователю со статус-кодом
404.Код обработчика:
from django.core.exceptions import ObjectDoesNotExistОбработчик написан, осталось только прописать
from rest_framework.response import Response
from rest_framework.views import APIView
from . import models, serializers
class GetFilePath(APIView):
@staticmethod
def get(request):
code = request.GET.get('code')
try:
file = models.PostFilesModel.objects.get(code=code)
file.increment_download_count()
serialized_data = serializers.FileModelSerializer(file)
return Response(serialized_data.data)
except ObjectDoesNotExist:
return Response(None, status=404)
URL-паттерн для обращения к нашему API.Перейдём в файл
urls.py нашего приложения. Что бы отделить паттерны страниц от паттернов API, под переменной urlpatterns, сделаем ещё одну с таким же именем. Только вместо = добавим сложение списков +=.В новой переменной, определим список и добавим в него переменную объект паттерна.
from django.urls import pathТеперь, запустив Django и обратившись с
from . import views, api
app_name = 'blog'
# Паттерны сайта
urlpatterns = [
path('', views.index, name='index'),
]
# Паттерны API
urlpatterns += [
path('bot/get-file/', api.GetFilePath.as_view()),
]
GET запросом при помощи программы Postman или библиотеки requests по пути https://127.0.0.1:8000/bot/get-file/?code=0 получим в ответ JSON содержащий необходимые нам данные.В следующем посте начнём писать функционал бота по запросу и отправке файла.
Файлы к посту, можно получить в боте по коду: 586344
Пост на сайте.
Поддержать канал.
#django #python #api #view #представление #запросы #get
Приветствую.
Внезапно для себя обнаружил, что группа для комментариев к каналу, может использоваться и просто, как группа для общения.
В общем, если будет интересно, то вот ссылка: https://t.iss.one/+cm-ITbA-JTczMTRi
Можем обсуждать там не только связанные с постами вещи 😉
#новости
Внезапно для себя обнаружил, что группа для комментариев к каналу, может использоваться и просто, как группа для общения.
В общем, если будет интересно, то вот ссылка: https://t.iss.one/+cm-ITbA-JTczMTRi
Можем обсуждать там не только связанные с постами вещи 😉
#новости
AIOgram3 7. Получение пути до файла по API
В предыдущем посте мы закончили писать API для бота. Вернёмся к боту и напишем функционал обращения к API и отправке файла пользователю.
Начнём с написания логики обращения к API.
В пакете
Для отправки запросов и получения данных, нам нужна библиотека
В начале файла создадим константу
В предыдущем посте мы закончили писать API для бота. Вернёмся к боту и напишем функционал обращения к API и отправке файла пользователю.
Начнём с написания логики обращения к API.
В пакете
botlogic создадим пакет utils. В данном пакете, будем писать логику не связанную с ботом. В пакете создадим файл api_actions.py.Для отправки запросов и получения данных, нам нужна библиотека
requests. Установим её командой pip install requests и добавим в requirements.txt.В начале файла создадим константу
API_URL и пропишем туда URL-адрес созданного ранее API. У меня это https://127.0.0.1:8000/bot/.❤1
Создадим функцию
В теле функции создадим переменную
В случае, если получим от API данные, тогда возвращаем из функции ответ в виде JSON.
Если же данных не будет(значит, что файла с таким кодом нет), вернём
После функции напишем
Подготовим всё необходимое к следующему посту.
В этом же пакете
Давайте сразу пропишем будущие команды, пусть их пока и нет. Откроем файл
В теле функции создадим переменную
Файлы к посту, можно получить в боте по коду: 733286
Пост на сайте.
Поддержать канал.
#aiogram #python #api #json #команды #меню
get_path, получающую аргумент code.В теле функции создадим переменную
response и получим в неё ответ на запрос. Запрос будет отправлять при помощи метода requests.get(), в параметры которого передадим API_URL + f'get-file/?code={code}'.В случае, если получим от API данные, тогда возвращаем из функции ответ в виде JSON.
Если же данных не будет(значит, что файла с таким кодом нет), вернём
None.import requestsИ для уверенности, что всё работает можно прямо здесь и протестировать.
API_URL = 'https://127.0.0.1:8000/bot/'
def get_path(code):
response = requests.get(API_URL + f"get-file/?code={code}")
if response:
return response.json()
return None
После функции напишем
print(get_path(0)), запустим Django в отдельном окне IDE и запустим наш скрипт. В выводе терминала должны получить JSON, похожий на питоновский словарь.{'title': 'Тестовый файл', 'file_path': 'C:\\Users\\proDream\\PycharmProjects\\pressanybutton\\pressanybutton\\media\\post_files\\68.zip'}
Отлично. API отрабатывает. Удалим принт, что бы при вызове функции не было лишних вызовов.Подготовим всё необходимое к следующему посту.
В этом же пакете
utils создадим файл statesform.py и commands.py. В файле statesform.py мы будем хранить группы состояний для машины состояний. В файле commands.py будет список команд бота, которые будут отображаться в виде кнопки меню у пользователя.Давайте сразу пропишем будущие команды, пусть их пока и нет. Откроем файл
commands.py и напишем асинхронную функцию set_commands в аргументы которой будет передаваться экземпляр класса Bot.В теле функции создадим переменную
commands и присвоим ей список. В списке будут находиться объекты класса BotCommand, в параметры которого передаётся команда и описание. Ниже запустим метод, присваивающий написанный ранее список команд нашему боту.from aiogram import BotОткроем файл
from aiogram.types import BotCommand, BotCommandScopeDefault
async def set_commands(bot: Bot):
commands = [
BotCommand(
command='start',
description='Начало работы'
),
BotCommand(
command='get_file',
description='Получить материалы'
),
BotCommand(
command='about',
description='Информация о боте'
)
]
await bot.set_my_commands(commands, BotCommandScopeDefault())
events.py в пакете handlers. В функции start_bot перед отправкой сообщения добавим добавление команд в меню:from botlogic.utils.commands import set_commandsВ следующем посте начнём писать команду
async def start_bot():
await set_commands(bot)
await bot.send_message(Secrets.admin_id, start_bot_msg())
get_file.Файлы к посту, можно получить в боте по коду: 733286
Пост на сайте.
Поддержать канал.
#aiogram #python #api #json #команды #меню
👍2
AIOgram3 8.1 Команда отправки файла
Работы много, по этому без лишних слов, приступим!
В пакете
В файле
Работы много, по этому без лишних слов, приступим!
В пакете
handlers создадим файл send_file.py и откроем его. Так же сразу откроем файл main.py, views.py и statesform.py. В основном работать будем в send_file.py, но другие три тоже будут нужны.В файле
send_file.py создадим асинхронную функцию send_file_start, в качестве аргументов она будет получать объект типа Message и FSMContext. FSMContext - это асинхронный контекст, который хранит информацию о текущем состоянии пользователя во время работы Telegram-бота. Он предоставляет функции для переключения между состояниями, сохранения и извлечения данных, а также другие операции, связанные с управлением состояниями.👍3
Перейдём в
Пропишем первое поле, он же шаг в машине состояний.
Первый шаг готов. Что тут происходит? При вызове команды, запускается машина состояний, тем самым все вводимые команды будут проигнорированы, а сообщения будут обработаны так, как этого требует логика.
После того как запустилась машина, пользователю отправляется сообщение, о необходимости ввести код и до тех пор, пока пользователь не отправит сообщение, перехода на следующий шаг не будет. Когда пользователь отправит сообщение, машина сменит состояние на следующую функцию.
Файлы к посту, можно получить в боте по коду: 523628
Пост на сайте.
Поддержать канал.
#aiogram #python #команды #меню #регистрация
views.py и создадим функцию send_file_start_msg, возвращающую строку с сообщением для пользователя.def send_file_start_msg():Теперь перейдём в файл
return """Для получения файла с дополнительными материалами к посту,
пожалуйста введите код из поста."""
statesform.py и создадим класс SendFileSteps унаследованный от StatesGroup.Пропишем первое поле, он же шаг в машине состояний.
from aiogram.fsm.state import StatesGroup, StateВернёмся в
class SendFileSteps(StatesGroup):
get_code_from_user = State()
send_file.py и в теле функции напишем отправку сообщения пользователю и переход к следующему шагу.from aiogram.fsm.context import FSMContextПерейдём в файл
from aiogram.types import Message
from botlogic import views
from botlogic.utils.statesform import SendFileSteps
async def send_file_start(message: Message, state: FSMContext):
await message.answer(views.send_file_start_msg())
await state.set_state(SendFileSteps.get_code_from_user)
main.py и после обработки событий запуска/остановки, зарегистрируем функцию на обработку команды get_file:from aiogram.filters import CommandПри регистрации функции
from botlogic.handlers import send_file
dp.message.register(send_file.send_file_start, Command(commands='get_file'))
echo, мы не указывали второго параметра, поскольку нам надо было обрабатывать все входящие сообщения. Здесь мы указали вторым параметром объект класса Command, являющийся фильтром. Первый шаг готов. Что тут происходит? При вызове команды, запускается машина состояний, тем самым все вводимые команды будут проигнорированы, а сообщения будут обработаны так, как этого требует логика.
После того как запустилась машина, пользователю отправляется сообщение, о необходимости ввести код и до тех пор, пока пользователь не отправит сообщение, перехода на следующий шаг не будет. Когда пользователь отправит сообщение, машина сменит состояние на следующую функцию.
Файлы к посту, можно получить в боте по коду: 523628
Пост на сайте.
Поддержать канал.
#aiogram #python #команды #меню #регистрация