Код на салфетке
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
Генерация кода для файла.
Отвлечёмся от основной темы поста.
Не уходя из файла models.py добавим генерацию кода для файла.

В классе PostFilesModel создадим метод генерации уникального кода и переопределим метод сохранения модели. Должно получиться так:
import random


def save(self, *args, **kwargs):
if not self.code:
self.code = self.generate_unique_code()
super().save(*args, **kwargs)

@staticmethod
def generate_unique_code():
code = random.randint(100000, 999999)
while PostFilesModel.objects.filter(code=code).exists():
code = random.randint(100000, 999999)
return code

Не обязательно, но поле code можно сделать полем "только для чтения".
Перейдём в файл admin.py и найдём класс PostFilesAdmin. Добавим в него всего одно поле:
    readonly_fields = ('code',)

Теперь код будет генерироваться при создании объекта, а в панели администратора нельзя будет его изменить.

Применим миграции:
python manage.py makemigrations
python manage.py migrate

Добавление в шаблон.
Возвращаемся к основной теме поста.
Для того чтобы отобразить ссылку на файл, в шаблоне необходимо обращаться к полю файл в модели файла и запрашивать его путь.
<h2 class="mb-3">Дополнительные материалы</h2>  
<a href="{{ post.file.file.path }}" class="mb-1">Скачать материалы и исходный код с сайта.</a>
<p class="mt-1">Или в <a href="https://t.iss.one/press_any_button_bot">Telegram-боте</a> по коду: <b>{{ post.file.code }}</b></p>

Изменение сериализатора.
Изменим сериализатор, чтобы он возвращал не только название файла и путь до него, но и поля из поста, например, ссылку на пост.
Добавим два новых поля:
- post_url - возвращающий ссылку на пост, для этого задействуем метод SerializerMethodField, поскольку получение полного URL до поста, это метод get_absolute_url. Параметр read_only=True позволяет, в случае если у файла нет связанного поста, получить None вместо исключения.
- post_telegram_link - возвращающий ссылку на пост в Telegram.

И метод, получающий URL поста, и добавляющий к нему UTM-метку для сбора статистики переходов.
В методе используем try-except, также чтобы избежать исключения, если у файла нет связанного поста.

Полный код сериализатора:
class FileModelSerializer(serializers.ModelSerializer):
file_path = serializers.SerializerMethodField()
post_url = serializers.SerializerMethodField()
post_telegram_link = serializers.StringRelatedField(source='post.telegram_link', read_only=True)

class Meta:
model = models.PostFilesModel
fields = ['title', 'file_path', 'post_url', 'post_telegram_link']

@staticmethod
def get_file_path(obj):
return obj.file.path if obj.file else None

@staticmethod
def get_post_url(obj: models.PostFilesModel):
try:
url = obj.post.get_absolute_url()
utm_params = '?utm_source=telegram&utm_medium=bot&utm_campaign=get_file'
return get_current_site(None).domain + url + utm_params
except ObjectDoesNotExist:
return None

Следующим постом внесём изменения в наш бот.

Файлы к посту, можно получить в боте по коду: 187343
1👍1
AIOgram3 11. Обновление для команды get_file

В прошлом посте, мы добавили связь между файлом и постом на сайте и добавили в передачу дополнительные данные.
Давайте обновим команду /get_file.

Обновление /get_file.
Откроем файл send_file.py.
В функции send_file_get_data нам нужно добавить дополнительные поля, которые мы получаем по API.

Находим строку, в которой отправляется файл - bot.send_document.
В аргументах у нас указан всего один параметр, который передаётся в сообщение пользователю - caption=views.file_caption(data['title']).
Давайте его расширим, добавив post_url и post_telegram_link:
await bot.send_document(message.chat.id, document=file, caption=views.file_caption(  
data['title'],
data['post_url'],
data['post_telegram_link']
))


Сообщение пользователю.
Теперь откроем файл views.py и найдём функцию file_caption.
В аргументы функции добавим новые - post_url и post_telegram_link.
В теле функции сделаем проверку, если post_url содержит данные, то мы возвращаем сообщение пользователю, в котором будет заголовок файла и две ссылки - на сайт и на канал.
Если же данных не будет, то возвращаем просто строку с заголовком файла.
def file_caption(file_title, post_url, post_telegram_link):
if post_url:
return f'Файл к посту: {file_title}\nПост на сайте: <a href="{post_url}">pressanybutton.ru</a>\nПост на канале: <a href="{post_telegram_link}">Код на салфетке</a>'
return f'Файл к посту: {file_title}'


Форматирование сообщений.
Ссылки можно отправлять и напрямую, но тогда ссылка будет занимать много места.
Telegram предоставляет три вида форматирования текста: markdown, markdownv2 и HTML.
Я остановился на HTML.

Чтобы добавить поддержку HTML-разметки в сообщениях, перейдём в файл settings.py.
Найдём переменную bot.
В параметры к классу Bot, сразу после передачи токена, добавим параметр parse_mode='HTML'.
bot = Bot(token=Secrets.token, parse_mode='HTML')


Чтобы проверить работу запустите бота и Django. В панели администратора Django откройте объект поста, в поле файл выберите имеющийся файл и сохраните.
Затем в боте запросите этот файл.
В сообщении к файлу, кроме заголовка, будут находиться ссылки на пост.

Файлы к посту, можно получить в боте по коду: 213307
👍1
Приветствую!

В длинных постах можно запутаться поэтому, собираю воедино всё, что есть на данный момент.


Оглавления
Для удобства навигации есть посты с оглавлениями по темам:

Список всех постов по Django

Список всех постов по AIOgram3

Список всех постов по Docker

Список всех постов по Полезным инструментам

Чат
У канала есть чат. Присоединяйтесь!


Бот и сайт
У канала также есть бот с материалами к постам

И сайт(в процессе наполнения вышедшими постами)


Поддержка
Если вам нравится канал и выходящий материал, поделитесь ссылкой с людьми, кому это тоже может быть интересно.
👍2🔥2👏1
Приветствую!

На канале уже 100 подписчиков!
Я невероятно рад.

Очень надеюсь, что мои посты вам интересны и полезны.

Спасибо.
🔥92
Приветствую.

Тема GPT и нейронок и не думает прекращаться. Кним присоединились и Яндекс со своим ЯндексGPT и Сбер со своим ГигаЧат. Вопрос. Интересно ли вам было бы увидеть пост-сравнение между ChatGPT, ЯндексGPT и ГигаЧатом? Накидаете тем в комменты?)
Anonymous Poll
68%
Интересно!
14%
Ну его...
18%
(╯ ° □ °) ╯ (┻━┻) Да кто этот ваш GPT такой?
Полезные инструменты. Jazzmin - шаблон панели администратора Django

Панель администратора Django мне всегда казалась не совсем удобной. Не в плане функционала, а в плане её внешнего вида.

Да, они добавили смену цветовой темы, но сам интерфейс устарел.

В интернете есть множество готовых решений для кастомизации внешнего вида панели администратора Django. Я же вам расскажу о том как установить шаблон, который мне понравился - Jazzmin.

Jazzmin.
Jazzmin - это современный, простой в использовании и настраиваемый шаблон для административной панели Django. Этот шаблон предлагает множество функций и настроек, чтобы сделать административную панель более удобной конкретно для вас.
Некоторые ключевые особенности Jazzmin:
1. Современный интерфейс: Jazzmin использует Bootstrap 4 и jQuery для создания современного и отзывчивого интерфейса.
2. Полная настройка: Jazzmin позволяет полностью настроить внешний вид административной панели. Вы можете изменить цвета, шрифты, логотипы и многое другое.
3. Улучшенная навигация: Jazzmin предлагает улучшенную навигацию с поиском по сайту, выпадающими меню и боковой панелью.
4. Интеграция с Django: Jazzmin полностью интегрирован с Django и поддерживает все его функции, включая авторизацию пользователей, управление контентом и т.д.
5. Мобильная адаптация: Jazzmin полностью адаптирован для мобильных устройств, что позволяет администраторам управлять сайтом с любого устройства.

Страница документации: https://django-jazzmin.readthedocs.io/

Установка.
Для установки выполним команду pip install django-jazzmin и добавим django-jazzmin==2.6.0 в requirements.txt.

Откроем файл settings.py и найдём INSTALLED_APPS.
Будьте предельно внимательны!
Добавляем jazzmin в самое начало списка. Строка jazzmin должна находиться над django.contrib.admin.

На этом установка закончена и перейдя в панель администратора, вы увидите новый интерфейс.

Кастомизация.
Jazzmin поддерживает кастомизацию. Более подробно об этом, читайте в документации.

В своём проекте я практически ничего не стал менять.

Для того, чтобы внести изменения во внешний вид или функционал, в файле settings.py есть два параметра:
- JAZZMIN_UI_TWEAKS - словарь, в котором прописываются изменённые элементы интерфейса.
- JAZZMIN_SETTINGS - словарь, в котором прописываются изменённые параметры конфигурации.

Мои настройки:
# Админпанель  
JAZZMIN_UI_TWEAKS = {
"theme": "darkly",
"sticky_actions": True,
"actions_sticky_top": True,
}
JAZZMIN_SETTINGS = {
"site_title": "Код на салфетке",
"site_brand": "Код на салфетке",
}


- theme - задаёт Bootstrap шаблон. Выбрать понравившийся можно на сайте: https://bootswatch.com/
- sticky_actions и actions_sticky_top - делает так, что элементы управления, такие как сохранить, удалить, сохранить и добавить другой объект и так далее, сохраняют своё положение при скролле страницы.
- site_title и site_brand - задают заголовок и название сайта в админпанели.

Также доступна возможность интерактивно настроить интерфейс под себя и получить полный код JAZZMIN_UI_TWEAKS.
Для этого в JAZZMIN_SETTINGS необходимо добавить строку "show_ui_builder" = True.

На этом всё. Пишите в комментариях, как вам данный модуль для Django, какую тему выбрали вы. Или может вы знаете другой, более удобный шаблон?
Приветствую.

Совместно с дизайнером проекта "Код на салфетке" запускаем Discord-сервер.

Сервер направлен в большую степень на дизайнеров, но и на программистов тоже.

Всем будем рады https://discord.gg/9baVxPma
🔥1
Django 25. Добавляем теги к постам

Теги являются важной частью любого информационного ресурса.
- Теги улучшают поисковую оптимизацию. Позволяют выделить ключевые слова в поиске.
- Фильтрация контента и создание связей на сайте. Пользователь сможет выбрать необходимый тег и посмотреть связанные с ним материалы.

django-taggit.
Для того чтобы добавить поддержку тегов в Django есть отличная библиотека django-taggit.

Установим библиотеку и добавим её в requirements.txt:
pip install django-taggit


И taggit добавим в INSTALLED_APPS.


Поле для тега.
Перейдём в файл models.py и найдём класс поста PostModel.

В нём добавим новое поле:
from taggit.managers import TaggableManager

tags = TaggableManager(blank=True)


Применим миграции:
python manage.py makemigrations
python manage.py migrate
Представление для тега.
Для вывода постов прикреплённых к тегу, сделаем новое представление и шаблон.

Перейдём в файл views.py и создадим новую функцию tag_page. Функция будет принимать в себя традиционный request и tag_name.

В теле функции в переменную posts получим отфильтрованные по имени тега посты.
posts = models.PostModel.objects.filter(tags__slug=tag_name).distinct()


Затем напишем контекст, содержащий имя тега и список постов.
context = {  
'tag_name': tag_name,
'posts': posts
}


И возвращаем рендер страницы.

Код функции:
def tag_page(request, tag_name):  
posts = models.PostModel.objects.filter(tags__slug=tag_name).distinct()

context = {
'tag_name': tag_name,
'posts': posts
}

return render(request,
'blog/tag_page.html',
context)



Шаблон страницы тега.
Перейдём в директорию с шаблонами и создадим файл tag_page.html.
Напишем простой шаблон (расширенный смотрите в материалах к посту):
{% extends "blog/base.html" %}
{% block title %}{{ tag_name | title }}{% endblock %}
{% block content %}
<div class="container">
<h1>{{ tag_name | title }}</h1>
<p>На этой странице представлены посты, отсортированные по имени тега {{ tag_name }}.</p>
<hr>
<div class="col-lg-9 col-sm-12 cat-block">
{% for post in posts %}
<div class="row">
<div class="col-lg-8 col-sm-12">
<h4><a href="{{ post.get_absolute_url }}">{{ post.title }}</a></h4>
<p class="lead"><a href="{{ post.category.get_absolute_url }}">{{ post.category }}</a>
| {{ post.author }} | {{ post.publish | date:"d F Y" }}</p>
{% for tag in post.tags.all %}
<a href="{% url 'blog:tag_page' tag.slug %}"><span
class="badge bg-success">{{ tag.name }}</span></a>
{% endfor %}
</div>
</div>
<hr class="m-3">
{% endfor %}
</div>
</div>
{% endblock %}


В файле latest_posts.html и post_page.html добавим отображение тегов:
{% for tag in post.tags.all %}  
<a href="{% url 'blog:tag_page' tag.slug %}"><span class="badge bg-success">{{ tag.name }}</span></a>
{% endfor %}


И, чтобы страницы тегов заработали, перейдём в urls.py и добавим в паттерны сайта новую страницу. Используем регулярное выражение в качестве паттерна для поддержки тегов на кириллице:
from django.urls import path, re_path

re_path(r'^tag/(?P<tag_name>[\w-]+)/$', views.tag_page, name='tag_page'),


Вот и всё, теперь у постов есть теги.

Файлы к посту, можно получить в https://t.iss.one/press_any_button_bot по коду: 772231
👍1
Приветствую.

На канале посты выходят раз в два-три дня, иногда будут чуть чаще, иногда чуть реже.

В это время канал простаивает и нет активности.

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

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

Спасибо.
🔥3
Django 26. Контекстные процессоры

На сайте есть блок ссылок, который отображается на страницах: категории, поста и главной. Все они передаются в шаблон в своём представлении. Это раздувает контекст представления лишними данными.
Было бы намного проще, если бы данные были доступны из всех шаблонов, где они задействованы, без раздувания контекста. Для этого в Django есть контекстные процессоры.

Контекстные процессоры - это функции, которые позволяют добавлять определенные данные в контекст каждого шаблона. Они используются, когда нужно сделать некоторые данные доступными на всех страницах сайта.
👍2
Создаём контекстный процессор.
В директории приложения создадим файл context_processors.py.

Напишем простую функцию get_social_links которая принимает только request.

В теле функции напишем возврат словаря, на подобии того, который представляет из себя контекст.

Ключом будет переменная, доступная в шаблоне, в моём случае это - social_links, а значением получение всех объектов модели - models.SocialLinksModel.objects.all().


Код.
from blog import models  


def get_social_links(request):
return {'social_links': models.SocialLinksModel.objects.all()}



Добавляем процессор в settings.py.
Для того чтобы наш контекстный процессор начал работу, перейдём в файл settings.py и найдём переменную TEMPLATES.

В этой переменной есть список context_processors.

Сюда добавим нашу функцию:
'blog.context_processors.get_social_links',



Убираем лишнее из представлений.
Перейдём в файл views.py и из всех представлений удалим передачу ссылок в шаблон.


Проверка работы.
Запустим Django и убедимся, что блоки ссылок остались на своих местах.


Таким нехитрым образом можно передавать во все шаблоны статические, не изменяемые от действий пользователя, данные.

Файлы к посту, можно получить в боте по коду: 201532
На днях была опубликована пробная викторина. Результаты которой показали, что есть необходимость пояснений, так как неверных ответов оказалась большая часть, а именно 51% от общего числа участвующих. В викторине приняло участие 27 человек.
В связи с этим, я решил написать пост, в котором расскажу про миграции в Django.
Спасибо за Вашу активность.


Миграции в Django
Миграции являются важной частью Django. Они позволяют распространять изменения в моделях приложения в базу данных.
В этой статье мы рассмотрим, что такое миграции, как ими пользоваться и как решать некоторые распространенные проблемы, связанные с ними.


Что такое миграции?
Миграции в Django - это способ автоматического обновления схемы базы данных, основанный на изменениях в моделях приложения. Они позволяют легко добавлять новые таблицы, поля или даже изменять существующую структуру базы данных, сохраняя при этом уже существующие данные.
👍1
Как использовать миграции?
Для работы с миграциями в Django необходимо выполнить несколько шагов.

Шаг 1: Создание и применение начальной миграции.
Первым делом нужно создать начальную миграцию для приложения.
Для этого нужно использовать команду python manage.py makemigrations <app_name>, где <app_name> - это имя приложения.
Эта команда создаст файл миграции, который будет содержать изменения в моделях.

Затем нужно применить миграцию к базе данных, используя команду python manage.py migrate.
Это применит все созданные миграции и обновит структуру базы данных в соответствии с вашими моделями.

Шаг 2: Изменение моделей.
После того, как была создана начальная миграция, вы можете вносить изменения в модели.
Это могут быть такие изменения, как добавление нового поля, удаление существующего поля или изменение типа поля.

Шаг 3: Создание и применение последующих миграций.
Когда вы вносите изменения в модели, необходимо создавать новую миграцию.
Для этого снова используйте команду python manage.py makemigrations <app_name>.
Django будет автоматически сравнивать текущую структуру базы данных с моделями и создаст новую миграцию, которая отражает эти изменения.

Затем примените новую миграцию командой python manage.py migrate. Django применит только новые миграции, которые еще не были применены, к базе данных.


Решение распространенных проблем.
В процессе работы с миграциями вы можете столкнуться с некоторыми распространенными проблемами.
Вот некоторые из них и их решения:

1. Конфликты миграций: Если у вас возникли конфликты между миграциями, вы можете попробовать использовать команду python manage.py makemigrations <app_name> --merge, чтобы объединить конфликтующие миграции.

2. Изменение моделей без создания миграций: Если вы внесли изменения в модели, но забыли создать соответствующие миграции, вы можете использовать команду python manage.py makemigrations --empty <app_name> для создания пустой миграции, а затем вручную внести необходимые изменения.

3. Откат изменений: Если вы хотите отменить последнюю миграцию и вернуть базу данных к предыдущему состоянию, вы можете использовать команду python manage.py migrate <app_name> <migration_name>, где <migration_name> - это имя миграции, до которой вы хотите откатиться.


Дополнительные возможности миграций.
1. Валидация миграций: Django обеспечивает механизм валидации миграций, чтобы убедиться, что они корректны и не приведут к ошибкам при применении. Вы можете использовать команду python manage.py makemigrations --check для проверки миграций на наличие ошибок перед их применением.

2. Многопользовательская среда: Если вы работаете в команде разработчиков, где каждый может вносить изменения в модели, существует возможность конфликтов между миграциями. В таком случае, рекомендуется использовать систему контроля версий, такую как Git, чтобы управлять и объединять миграции.

3. Управление данными: Миграции в Django фокусируются на изменении структуры базы данных, но иногда вам также может потребоваться изменить или манипулировать данными в базе данных. Для этого вы можете использовать файлы миграций, чтобы добавить специальные операции, такие как заполнение полей или обновление данных.

4. Миграции с отключенной автоматической генерацией: Иногда автоматическая генерация миграций может быть неудобной или вам просто нужно создать миграции вручную. Django также позволяет создавать миграции без использования команды makemigrations или через отключение автоматической генерации миграций в настройках проекта.

5. Множественные базы данных: Если у вас есть несколько баз данных в проекте, Django предоставляет возможность создавать миграции для каждой отдельной базы данных и применять их отдельно. Это полезно при наличии разных баз данных для разных частей проекта или при использовании шардинга данных.
6. Миграции и тестирование: При написании тестов для проекта важно учитывать миграции. Django предоставляет механизм, который позволяет создавать временные базы данных для каждого тестового случая с примененными миграциями. Это помогает гарантировать правильность работы кода и базы данных в тестовом окружении.

7. Документация и сообщество: Django имеет обширную документацию и активное сообщество разработчиков, которые могут помочь вам разобраться с миграциями и решить любые проблемы, с которыми вы столкнетесь. Не стесняйтесь обращаться к официальной документации и форумам, чтобы получить дополнительную поддержку.

Миграции в Django - мощный инструмент, который позволяет легко управлять изменениями в структуре базы данных. Это позволяет быстро развивать и поддерживать приложение, сохраняя при этом целостность данных.
Надеюсь, эта статья помогла вам понять основы использования миграций в Django.
2