Код на салфетке
2.22K subscribers
746 photos
14 videos
2 files
788 links
Канал для тех, кому интересно программирование на Python и не только.

Сайт: https://pressanybutton.ru/
Чат: https://t.iss.one/+Li2vbxfWo0Q4ZDk6
Заметки автора: @writeanynotes

Реклама и взаимопиар: @Murzyev1995
Сотрудничество и др.: @proDreams
Download Telegram
Django 7. Первое представление

В интернете всё построено на запросах. Открывая любую страницу, мы делаем запрос к серверу "хочу попасть на такую-то страницу", а сервер уже обрабатывает его и возвращает ответ на запрос с содержимым страницы.
Для формирования ответа на запрос с доступом к той или иной странице в Django отвечают, так называемые "представления", они же "views".
Давайте создадим наше первое простое представление, для возврата содержимого базового шаблона посетителю сайта.

Переходим в файл views.py расположенный в директории приложения.
Под имеющимся в файле импортом добавим функцию со следующим кодом:
def index(request):
return render(request,
'blog/base.html')

Мы создали представление index, получающего запрос от пользователя.
Поскольку у нас пока заглушка и данные передавать нам никакие не нужно, сразу переходим к возврату ответа пользователю. За это отвечает функция render, в которую мы передаём запрос, а так же путь до файла шаблона.
👍3
Теперь получив запрос на отображение главной страницы сайта, Django вернёт её содержимое. Только вот Django, пока ничего не знает, о том, где у нас главная страница и как строить маршрутизацию по URL-адресам.

В директории приложения создадим файл urls.py.
Файл urls.py в Django имеет важное значение. Он определяет, как URL-запросы будут соотноситься с определенными представлениями и функциями. В этом файле определяются URL-шаблоны, которые связывают входящие URL-запросы с соответствующими представлениями. Представления обрабатывают запросы и возвращают соответствующие HTTP-ответы.

Добавим следующий код:
from django.urls import path

from blog import views

app_name = 'blog'
urlpatterns = [
path('', views.index, name='index'),
]
В переменной app_name указываем имя приложения, для корректного сопоставления URL-адресов.
В переменную urlpatterns присваиваем список. Внутри списка вфзфывем функцию path, формирующую маршрут и URL-адрес.
В неё передаём:
- Первым параметром URL-паттерн. Пустые кавычки означают, что паттерн будет применён к основному адресу сайта, например pressanybutton.ru, а если пропишем "blog", тогда он будет срабатывать, когда будем переходить по адресу pressanybutton.ru/blog
- Вторым параметром указываем, какое представление необходимо вызвать при запросе данного адреса.
- В третьем параметре указываем имя для пути.
Также обратите внимание на вторую строку импорта, замените blog на имя вашего приложения

Теперь, надо сообщить Django о том, что у нас есть приложение со своим набором URL-паттернов. Для этого, перейдём в директорию проекта и откроем файл urls.py.
Там уже будет переменная urlpatterns с прописанным паттерном панели администратора.
Добавим в имеющийся список новую строку с адресами приложения:
from django.urls import path, include

urlpatterns = [
# ...
path('', include('blog.urls', namespace='blog')),
]
В данной строке, мы сообщаем Django, что по пути сайта мы будем использовать URL-паттерны из приложения.

И сразу добавим сюда определение путей для медиа и статических файлов. В этом же файле, только ниже добавьте следующие строки:
from django.conf.urls.static import static  
from django.conf import settings

urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

Запустим Django командой python manage.py runserver и перейдём на страницу.
Должна отобразиться страница с заглушкой. Такая-же как https://pressanybutton.ru

В следующем посте, начнём делать структуру Telegram-бота

Файлы к посту, можно получить в боте по коду: 772660
Пост на сайте.
Поддержать канал.

#django #python #представление #views #render #url_паттерны
👍3
AIOgram3 5.1. Создание структуры

Большинство проектов не ограничиваются одним лишь файлом main.py, напротив, часто проекты состоят из множества файлов с кодом конкретной логики. Для этого в Python предусмотрена "пакетная" система. Пакет является директорией, которая содержит в себе модули и подпакеты. Он позволяет логически объединять связанный функционал и предоставляет простой способ управления зависимостями и кодом в рамках проекта.

Создадим основной пакет botlogic со всей будущей логикой.
Если, вы работаете в PyCharm или другой Python-направленной IDE, то достаточно в контекстном меню директории выбрать "New - Python Package".
Но создать пакет можно и вручную.
Для этого необходимо создать директорию с необходимым именем пакета. Внутри директории создать пустой файл __init__.py. Данный файл сообщит интерпретатору, что директория является пакетом.
При каждом создании пакета, необходимо создавать внутри пустой файл __init__.py
👍3
В этом пакете создадим файл 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 добавляем пустую строку и вставляем туда код логгера, а в начло файла добавляем строку импорта:
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. Информирование администратора

Теперь давайте добавим функционал информирование админа бота о его запуске или остановке.

Перейдём в файл 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
Мы создали две асинхронные функции 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 модель - это класс, который определяет структуру и поведение данных в вашем приложении. Он представляет таблицу в базе данных, где каждое поле в модели соответствует столбцу в таблице.

Давайте создадим первую модель, которая в последствии будет расширена.
Откроем файл 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. В конце файла прописать 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. Доделаем бота и начнём делать блог на сайте.

Я очень надеюсь, что вам нравится, что я делаю. По этому прошу, рассказать о канале друзьям или людям, кому это тоже может быть интересно.

Ещё, хотелось бы видеть больше обратной связи по материалам.
Достаточно ли понятно написано? Нужно ли делать более длинные? И другие возникающие у вас вопросы.

Спасибо вам, за то, что читаете.
🔥8
Django 10. Пишем API - Сериализатор

С места в карьер! Там где все обычно пишут модели, представления и странички для блога, я же предлагаю окунуться сразу в нечто более полезное, а именно решить поставленную задачу.
Суть задачи в следующем: Необходимо, что бы Telegram-бот обращался к Django по определённому адресу, передавая цифровой код, а в ответ получал расположение файла на сервере и собственно отправлял этот файл пользователю. Этим и займёмся в ближайшие несколько постов, а потом уже можно будет отдохнуть за созданием сайта.

Первым делом необходимо установить библиотеку djangorestframework командой pip install djangorestframework и добавить установленную версию в requirements.txt.
После этого, в директории приложения создадим два файла: api.py и serializers.py.
В файле api.py будем писать обработчики запросов, а в файле serializers.py будет происходить сериализация из данных объекта модели в JSON.
Начинать можно как с сериализатора, так и с обработчика. Но я всё таки рекомендую начинать с сериализатора, так можно сразу определиться с тем, какие данные нам нужно возвращать.

Перейдём в файл 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 его значение.
Создадим переменную 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

from . import views, api

app_name = 'blog'
# Паттерны сайта
urlpatterns = [
path('', views.index, name='index'),
]

# Паттерны API
urlpatterns += [
path('bot/get-file/', api.GetFilePath.as_view()),
]
Теперь, запустив Django и обратившись с 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
Можем обсуждать там не только связанные с постами вещи 😉

#новости
AIOgram3 7. Получение пути до файла по 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
Создадим функцию 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