Django 25. Добавляем теги к постам
Теги являются важной частью любого информационного ресурса.
- Теги улучшают поисковую оптимизацию. Позволяют выделить ключевые слова в поиске.
- Фильтрация контента и создание связей на сайте. Пользователь сможет выбрать необходимый тег и посмотреть связанные с ним материалы.
django-taggit.
Для того чтобы добавить поддержку тегов в Django есть отличная библиотека
Установим библиотеку и добавим её в
И
Поле для тега.
Перейдём в файл
В нём добавим новое поле:
Применим миграции:
Теги являются важной частью любого информационного ресурса.
- Теги улучшают поисковую оптимизацию. Позволяют выделить ключевые слова в поиске.
- Фильтрация контента и создание связей на сайте. Пользователь сможет выбрать необходимый тег и посмотреть связанные с ним материалы.
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
Представление для тега.
Для вывода постов прикреплённых к тегу, сделаем новое представление и шаблон.
Перейдём в файл
В теле функции в переменную
Затем напишем контекст, содержащий имя тега и список постов.
И возвращаем рендер страницы.
Код функции:
Шаблон страницы тега.
Перейдём в директорию с шаблонами и создадим файл
Напишем простой шаблон (расширенный смотрите в материалах к посту):
В файле
И, чтобы страницы тегов заработали, перейдём в
Вот и всё, теперь у постов есть теги.
Файлы к посту, можно получить в https://t.iss.one/press_any_button_bot по коду: 772231
Для вывода постов прикреплённых к тегу, сделаем новое представление и шаблон.
Перейдём в файл
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 и для чего они используются?
Что такое миграции в Django и для чего они используются?
Anonymous Quiz
16%
Это способ создания резервной копии базы данных для безопасного хранения данных.
42%
Это автоматически создаваемые скрипты, которые изменяют структуру базы данных при развитии приложени
13%
Это функция, позволяющая перенести приложение на другой сервер без потери данных.
29%
Это способ управления версиями приложения и отслеживания изменений кода в системе контроля версий.
👍2
Django 26. Контекстные процессоры
На сайте есть блок ссылок, который отображается на страницах: категории, поста и главной. Все они передаются в шаблон в своём представлении. Это раздувает контекст представления лишними данными.
Было бы намного проще, если бы данные были доступны из всех шаблонов, где они задействованы, без раздувания контекста. Для этого в Django есть
Контекстные процессоры - это функции, которые позволяют добавлять определенные данные в контекст каждого шаблона. Они используются, когда нужно сделать некоторые данные доступными на всех страницах сайта.
На сайте есть блок ссылок, который отображается на страницах: категории, поста и главной. Все они передаются в шаблон в своём представлении. Это раздувает контекст представления лишними данными.
Было бы намного проще, если бы данные были доступны из всех шаблонов, где они задействованы, без раздувания контекста. Для этого в Django есть
контекстные процессоры.Контекстные процессоры - это функции, которые позволяют добавлять определенные данные в контекст каждого шаблона. Они используются, когда нужно сделать некоторые данные доступными на всех страницах сайта.
👍2
Создаём контекстный процессор.
В директории приложения создадим файл
Напишем простую функцию
В теле функции напишем возврат словаря, на подобии того, который представляет из себя контекст.
Ключом будет переменная, доступная в шаблоне, в моём случае это -
Код.
Добавляем процессор в settings.py.
Для того чтобы наш контекстный процессор начал работу, перейдём в файл
В этой переменной есть список
Сюда добавим нашу функцию:
Убираем лишнее из представлений.
Перейдём в файл
Проверка работы.
Запустим Django и убедимся, что блоки ссылок остались на своих местах.
Таким нехитрым образом можно передавать во все шаблоны статические, не изменяемые от действий пользователя, данные.
Файлы к посту, можно получить в боте по коду: 201532
В директории приложения создадим файл
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 - это способ автоматического обновления схемы базы данных, основанный на изменениях в моделях приложения. Они позволяют легко добавлять новые таблицы, поля или даже изменять существующую структуру базы данных, сохраняя при этом уже существующие данные.
В связи с этим, я решил написать пост, в котором расскажу про миграции в Django.
Спасибо за Вашу активность.
Миграции в Django
Миграции являются важной частью Django. Они позволяют распространять изменения в моделях приложения в базу данных.
В этой статье мы рассмотрим, что такое миграции, как ими пользоваться и как решать некоторые распространенные проблемы, связанные с ними.
Что такое миграции?
Миграции в Django - это способ автоматического обновления схемы базы данных, основанный на изменениях в моделях приложения. Они позволяют легко добавлять новые таблицы, поля или даже изменять существующую структуру базы данных, сохраняя при этом уже существующие данные.
👍1
Как использовать миграции?
Для работы с миграциями в Django необходимо выполнить несколько шагов.
Шаг 1: Создание и применение начальной миграции.
Первым делом нужно создать начальную миграцию для приложения.
Для этого нужно использовать команду
Эта команда создаст файл миграции, который будет содержать изменения в моделях.
Затем нужно применить миграцию к базе данных, используя команду
Это применит все созданные миграции и обновит структуру базы данных в соответствии с вашими моделями.
Шаг 2: Изменение моделей.
После того, как была создана начальная миграция, вы можете вносить изменения в модели.
Это могут быть такие изменения, как добавление нового поля, удаление существующего поля или изменение типа поля.
Шаг 3: Создание и применение последующих миграций.
Когда вы вносите изменения в модели, необходимо создавать новую миграцию.
Для этого снова используйте команду
Django будет автоматически сравнивать текущую структуру базы данных с моделями и создаст новую миграцию, которая отражает эти изменения.
Затем примените новую миграцию командой
Решение распространенных проблем.
В процессе работы с миграциями вы можете столкнуться с некоторыми распространенными проблемами.
Вот некоторые из них и их решения:
1. Конфликты миграций: Если у вас возникли конфликты между миграциями, вы можете попробовать использовать команду
2. Изменение моделей без создания миграций: Если вы внесли изменения в модели, но забыли создать соответствующие миграции, вы можете использовать команду
3. Откат изменений: Если вы хотите отменить последнюю миграцию и вернуть базу данных к предыдущему состоянию, вы можете использовать команду
Дополнительные возможности миграций.
1. Валидация миграций: Django обеспечивает механизм валидации миграций, чтобы убедиться, что они корректны и не приведут к ошибкам при применении. Вы можете использовать команду
2. Многопользовательская среда: Если вы работаете в команде разработчиков, где каждый может вносить изменения в модели, существует возможность конфликтов между миграциями. В таком случае, рекомендуется использовать систему контроля версий, такую как Git, чтобы управлять и объединять миграции.
3. Управление данными: Миграции в Django фокусируются на изменении структуры базы данных, но иногда вам также может потребоваться изменить или манипулировать данными в базе данных. Для этого вы можете использовать файлы миграций, чтобы добавить специальные операции, такие как заполнение полей или обновление данных.
4. Миграции с отключенной автоматической генерацией: Иногда автоматическая генерация миграций может быть неудобной или вам просто нужно создать миграции вручную. Django также позволяет создавать миграции без использования команды
5. Множественные базы данных: Если у вас есть несколько баз данных в проекте, Django предоставляет возможность создавать миграции для каждой отдельной базы данных и применять их отдельно. Это полезно при наличии разных баз данных для разных частей проекта или при использовании шардинга данных.
Для работы с миграциями в 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.
7. Документация и сообщество: Django имеет обширную документацию и активное сообщество разработчиков, которые могут помочь вам разобраться с миграциями и решить любые проблемы, с которыми вы столкнетесь. Не стесняйтесь обращаться к официальной документации и форумам, чтобы получить дополнительную поддержку.
Миграции в Django - мощный инструмент, который позволяет легко управлять изменениями в структуре базы данных. Это позволяет быстро развивать и поддерживать приложение, сохраняя при этом целостность данных.
Надеюсь, эта статья помогла вам понять основы использования миграций в Django.
❤2
Приветствую.
Давайте немного порешаем задачки.
Сегодняшнюю задачу, давали на одном из курсов в качестве домашней работы. Предлагаю решить её и вам.
Можно решать на любом удобном для вас языке, а также не возбраняется обсуждение.
Задача.
Представить поле для игры в "Крестики-Нолики", размером 3x3 в виде двумерного массива с числами, представляющими из себя состояние ячеек.
Доступно 4 состояния:
- 0 - пустая ячейка.
- 1 - ячейка с крестиком
- 2 - ячейка с ноликом
- 3 - резервное значение
Необходимо записать 9 значений в файл, но так, чтобы размер файла был равен трём байтам.
После чего, реализовать возможность прочесть файл и восстановить исходный двумерный массив.
Давайте немного порешаем задачки.
Сегодняшнюю задачу, давали на одном из курсов в качестве домашней работы. Предлагаю решить её и вам.
Можно решать на любом удобном для вас языке, а также не возбраняется обсуждение.
Задача.
Представить поле для игры в "Крестики-Нолики", размером 3x3 в виде двумерного массива с числами, представляющими из себя состояние ячеек.
Доступно 4 состояния:
- 0 - пустая ячейка.
- 1 - ячейка с крестиком
- 2 - ячейка с ноликом
- 3 - резервное значение
Необходимо записать 9 значений в файл, но так, чтобы размер файла был равен трём байтам.
После чего, реализовать возможность прочесть файл и восстановить исходный двумерный массив.
Полезные инструменты - Переключатель цветовой темы в Bootstrap5
После запуска сайта, я получил несколько вопросов касательно переключателя цветовой темы на сайте, а именно, как он реализован.
Ответ прост - читайте документацию: https://getbootstrap.com/docs/5.3/customize/color-modes/
Но, если бы всё было так просто, не было бы вопросов и поста.
Пост будет без привязки к
В качестве IDE для HTML я рекомендую использовать
Скачать его можно по ссылке: https://code.visualstudio.com/
Благодаря плагинам, в нём удобно работать с HTML и CSS файлами. Именно на примере работы в нём и будет пост.
После запуска сайта, я получил несколько вопросов касательно переключателя цветовой темы на сайте, а именно, как он реализован.
Ответ прост - читайте документацию: https://getbootstrap.com/docs/5.3/customize/color-modes/
Но, если бы всё было так просто, не было бы вопросов и поста.
Пост будет без привязки к
Django или к чему-либо ещё.В качестве IDE для HTML я рекомендую использовать
Visual Studio Code. Скачать его можно по ссылке: https://code.visualstudio.com/
Благодаря плагинам, в нём удобно работать с HTML и CSS файлами. Именно на примере работы в нём и будет пост.
Подготовка.
Создайте директорию в которой будете работать и откройте её в
Создайте в ней две директории:
Переходим по ссылке и скачиваем последнюю актуальную версию нажав по синей кнопке
В скачанном архиве будет также две директории, как те, которые создали ранее, но не спешите всё распаковывать!.
В директории
В чём разница?
Обычный
1. Обычный CSS/JS файл:
- Содержит человекочитаемый код с комментариями и форматированием.
- Используется во время разработки и обслуживания сайта.
- Размер файла может быть больше из-за комментариев и дополнительного форматирования.
2. Min CSS/JS файл:
- Является минифицированной (сжатой) версией файла.
- Отсутствуют комментарии и лишние пробелы.
- Используется для оптимизации загрузки и ускорения работы веб-страницы.
- Размер файла обычно меньше, чем размер обычного файла, благодаря удалению ненужных символов.
Выбирайте тот вариант, который вам удобнее и помещайте в соответствующую директорию. Я выбрал min версии, поскольку не планирую вносить правки в файлы Bootstrap.
Для тех, кто знакомится с Bootstrap лучше подойдёт полная версия. Можно будет посмотреть как реализованы те или иные классы, код
Собственный файл скрипта.
Помимо файла скриптов от Bootstrap, нам нужен и собственный.
Создадим в директории
В этом файле будет находиться код, отвечающий за смену цветовой темы.
Нужно ли скачивать Bootstrap?
Один из самых частых вопросов - нужно ли скачивать файлы локально, если их можно подключить по ссылке?
Ответ - не обязательно.
Подключение по ссылке может ускорить работу сайта за счёт CDN.
CDN выбирает ближайший сервер к пользователю и отдаёт оттуда файл. Но может и замедлить, если сервер сайта находится ближе, а CDN далеко.
И ещё одна актуальная проблема - блокировки интернет ресурсов. Если CDN будет заблокирован для пользователя или пользователь заблокирован на CDN - файл не будет загружен и это вызовет проблемы с отображением сайта.
Проще говоря, скачивание файла локально, это в первую очередь безопасность владельца сайта от возможных проблем со стороны получения пользователем содержимого.
Подключаем Bootstrap.
Начнём с самого начала - создания
Создадим файл
В файле пишем символ восклицательного знака
Для подключения
Тут мы указываем путь к файлу
Для подключения
Тут указываем путь к файлу
Вот и всё. Bootstrap подключен к странице (сайту).
JavaScript смены цветовой темы.
Для того, чтобы цветовая тема изменялась и, что немаловажно, запоминалась, необходим JavaScript код.
Откроем файл
Создайте директорию в которой будете работать и откройте её в
VS Code.Создайте в ней две директории:
css и js. В этих директориях будут находится файлы Bootstrap.Переходим по ссылке и скачиваем последнюю актуальную версию нажав по синей кнопке
Download в первом же блоке Compiled CSS and JS.В скачанном архиве будет также две директории, как те, которые создали ранее, но не спешите всё распаковывать!.
В директории
css нас интересуют два файла - bootstrap.css и bootstrap.min.css, а в директории js - bootstrap.bundle.js и bootstrap.bundle.min.js.В чём разница?
Обычный
css/js файл (например, style.css или script.js) и min.css/js файл (например, style.min.css или script.min..js) представляют собой два разных способа организации и оптимизации кода CSS/JS.1. Обычный CSS/JS файл:
- Содержит человекочитаемый код с комментариями и форматированием.
- Используется во время разработки и обслуживания сайта.
- Размер файла может быть больше из-за комментариев и дополнительного форматирования.
2. Min CSS/JS файл:
- Является минифицированной (сжатой) версией файла.
- Отсутствуют комментарии и лишние пробелы.
- Используется для оптимизации загрузки и ускорения работы веб-страницы.
- Размер файла обычно меньше, чем размер обычного файла, благодаря удалению ненужных символов.
Выбирайте тот вариант, который вам удобнее и помещайте в соответствующую директорию. Я выбрал min версии, поскольку не планирую вносить правки в файлы Bootstrap.
Для тех, кто знакомится с Bootstrap лучше подойдёт полная версия. Можно будет посмотреть как реализованы те или иные классы, код
JavaScript.Собственный файл скрипта.
Помимо файла скриптов от Bootstrap, нам нужен и собственный.
Создадим в директории
js новый файл с именем script.js.В этом файле будет находиться код, отвечающий за смену цветовой темы.
Нужно ли скачивать Bootstrap?
Один из самых частых вопросов - нужно ли скачивать файлы локально, если их можно подключить по ссылке?
Ответ - не обязательно.
Подключение по ссылке может ускорить работу сайта за счёт CDN.
CDN выбирает ближайший сервер к пользователю и отдаёт оттуда файл. Но может и замедлить, если сервер сайта находится ближе, а CDN далеко.
И ещё одна актуальная проблема - блокировки интернет ресурсов. Если CDN будет заблокирован для пользователя или пользователь заблокирован на CDN - файл не будет загружен и это вызовет проблемы с отображением сайта.
Проще говоря, скачивание файла локально, это в первую очередь безопасность владельца сайта от возможных проблем со стороны получения пользователем содержимого.
Подключаем Bootstrap.
Начнём с самого начала - создания
html файла и подключения Bootstrap5.Создадим файл
index.html.В файле пишем символ восклицательного знака
! и нажимаем клавишу tab. Это создаст базовую структуру.Для подключения
CSS, в блоке тега head добавляем строку:<link href="css/bootstrap.min.css" rel="stylesheet">
Тут мы указываем путь к файлу
bootstrap.min.css и сообщаем, что это таблица стилей.Для подключения
JavaScript от Bootstrap и наш собственный, в конце блока тега body добавляем строки:<script src="js/bootstrap.bundle.min.js"></script>
<script src="js/script.js"></script>
Тут указываем путь к файлу
bootstrap.bundle.min.js и нашему script.js.Вот и всё. Bootstrap подключен к странице (сайту).
JavaScript смены цветовой темы.
Для того, чтобы цветовая тема изменялась и, что немаловажно, запоминалась, необходим JavaScript код.
Откроем файл
script.js и пропишем код предоставленный разработчиками Bootstrap:Код примера ищите в файле script-dev.js в архиве с материалами к посту.
Описание функций:
1.
2.
3.
4.
5. Последний блок кода добавляет обработчик событий к
Добавляем переключение цветовой темы.
Теперь нужно добавить в шаблон метку текущей цветовой темы и переключатель.
Для того, чтобы Bootstrap понял, какая цветовая тема в данный момент используется, в самом начале файла, внутри тега
Должно быть вот так:
Затем нужно добавить переключатель.
Вариант из документации.
Разработчики подготовили пример шапки с переключателем цветовой темы в виде выпадающего списка.
Подробнее можно ознакомиться в документации на GitHub: https://github.com/twbs/examples/tree/main/color-modes
Добавляем следующий код в блок
Открываем файл
На открывшейся странице увидим пример шапки и переключатель темы. Он должен корректно отрабатывать переключение темы.
Мой вариант.
У себя на сайте, я сделал кнопку вида
В теге
В директории
В файле напишем стили для переключателя, добавляющие иконки по краям:
Иконки приложены к материалам поста
Изменению также подвергся и
Откройте страницу в браузере и проверьте, как отрабатывает переключатель.
Вот и всё. Кастомизация под конкретный шаблон и вид переключателя не должна оказаться сложной.
Разработчики предоставили обширные материалы по реализации, а дальше, как говориться - всё в ваших руках.
Файлы к посту, можно получить в боте по коду: 166197
1.
getStoredTheme и setStoredTheme - это функции для чтения и записи темы в локальное хранилище браузера.2.
getPreferredTheme - эта функция сначала проверяет, есть ли тема в локальном хранилище. Если нет, она проверяет предпочтения пользователя на темную тему в настройках системы.3.
setTheme - эта функция устанавливает тему в качестве атрибута data-bs-theme в элементе document.documentElement (обычно это <html> ). Если тема 'auto' и пользователь предпочитает темную тему, устанавливается темная тема, иначе устанавливается выбранная тема.4.
showActiveTheme - эта функция обновляет пользовательский интерфейс для отображения активной темы. Она делает кнопку выбранной темы активной и устанавливает соответствующую иконку темы.5. Последний блок кода добавляет обработчик событий к
window.matchMedia('(prefers-color-scheme: dark)') . Если пользователь изменяет предпочтение на темную тему в системных настройках, код проверяет, не установлена ли уже темная или светлая тема. Если нет, он устанавливает предпочитаемую тему.Добавляем переключение цветовой темы.
Теперь нужно добавить в шаблон метку текущей цветовой темы и переключатель.
Для того, чтобы Bootstrap понял, какая цветовая тема в данный момент используется, в самом начале файла, внутри тега
html, сразу после lang="en" добавим метку текущей темы - data-bs-theme="dark".Должно быть вот так:
<html lang="en" data-bs-theme="dark">
Затем нужно добавить переключатель.
Вариант из документации.
Разработчики подготовили пример шапки с переключателем цветовой темы в виде выпадающего списка.
Подробнее можно ознакомиться в документации на GitHub: https://github.com/twbs/examples/tree/main/color-modes
Добавляем следующий код в блок
body до подключения JS файлов:Код примера ищите в файле index-dev.html в архиве с материалами к посту.
Открываем файл
index.html в браузере, для этого можно нажать кнопку Go Live в нижней-правой части окна VS Code.На открывшейся странице увидим пример шапки и переключатель темы. Он должен корректно отрабатывать переключение темы.
Мой вариант.
У себя на сайте, я сделал кнопку вида
switch. Как по мне, такой вариант органичнее выглядит.В теге
body до подключения JS файлов добавим следующий код:Код примера ищите в файле index-my.html в архиве с материалами к посту.
В директории
css создадим файл style.css и подключим его в теге head:<link href="css/style.css" rel="stylesheet">
В файле напишем стили для переключателя, добавляющие иконки по краям:
.switch-icons {
display: flex;
align-items: center;
flex-wrap: nowrap;
padding: 0;
margin: 0;
}
.switch-icons::before {
content: url(../svg/sun-fill.svg);
width: 24px;
height: 24px;
margin-right: 3px;
filter: invert(1);
}
.form-check-label {
content: url(../svg/moon-stars-fill.svg);
width: 12px;
height: 12px;
margin-left: 8px;
filter: invert(1);
}
.form-switch .form-check-input {
margin: 0;
}Иконки приложены к материалам поста
Изменению также подвергся и
JS код:Код примера ищите в файле csript-my.js в архиве с материалами к посту.
Откройте страницу в браузере и проверьте, как отрабатывает переключатель.
Вот и всё. Кастомизация под конкретный шаблон и вид переключателя не должна оказаться сложной.
Разработчики предоставили обширные материалы по реализации, а дальше, как говориться - всё в ваших руках.
Файлы к посту, можно получить в боте по коду: 166197
👍1
Так и запишем - задача не вызвала вообще никакой реакции.
Сегодня будет простая викторина.. Какой командой можно создать новый проект в Django?
Сегодня будет простая викторина.. Какой командой можно создать новый проект в Django?
Anonymous Quiz
25%
python manage.py createproject myproject
46%
django-admin startproject myproject
4%
django-admin newproject myproject
14%
python manage.py projectstart myproject
11%
django-admin createproject myproject
🔥2
Django 27.1 Представления на основе классов
В предыдущих постах я рассказывал о представлениях на основе функций, они же
Подход писать функциональные представления хорош на начальном этапе. Он даёт понимание работы представлений.
Однако в последствии, код представлений будет усложняться и разрастаться, что может сделать их трудно читаемыми и перегруженными. Также, в большинстве гайдов, материалов и документациях примеры даются на классовых представлениях.
Классовые представления.
Классовые представления, они же
Классовые представления в Django обеспечивают ряд преимуществ по сравнению с функциональными представлениями. Они позволяют использовать принципы ООП, такие как наследование и полиморфизм, что делает код более организованным и поддерживаемым.
В предыдущих постах я рассказывал о представлениях на основе функций, они же
function-based views или FBV.Подход писать функциональные представления хорош на начальном этапе. Он даёт понимание работы представлений.
Однако в последствии, код представлений будет усложняться и разрастаться, что может сделать их трудно читаемыми и перегруженными. Также, в большинстве гайдов, материалов и документациях примеры даются на классовых представлениях.
Классовые представления.
Классовые представления, они же
class-based views или CBV. Представляют собой альтернативный подход к созданию представлений. Они основаны на использовании классов вместо функций, что позволяет лучше структурировать код и повысить его переиспользование.Классовые представления в Django обеспечивают ряд преимуществ по сравнению с функциональными представлениями. Они позволяют использовать принципы ООП, такие как наследование и полиморфизм, что делает код более организованным и поддерживаемым.
Классы-представления могут быть очень гибкими и настраиваемыми. Можно определить свои собственные классы-представления, которые наследуются от базовых классов и расширяют их функциональность в соответствии с требованиями проекта. Это позволяет сократить дублирование кода, упростить его поддержку и улучшить его читабельность.
При использования классов-представлений можно определить методы, такие как
Различия между функциональными и классовыми представлениями:
1. Структура кода: В функциональных представлениях код разбит на функции, которые выполняют определенные действия. В классовых представлениях код организован в виде классов, которые содержат методы для обработки запросов.
2. Наследование: В классовых представлениях можно использовать наследование, что позволяет переиспользовать код и добавлять новую функциональность. В функциональных представлениях такая возможность отсутствует.
3. Расширяемость: Классовые представления позволяют легко добавлять новые методы и функциональность без изменения основного кода. В функциональных представлениях это может быть сложнее.
4. Миксины: Классовые представления поддерживают использование миксинов, которые представляют собой классы с определенными методами, которые можно добавить к основному классу представления для расширения его функциональности.
5. Читаемость кода: Классовые представления могут быть более читаемыми и понятными, особенно для разработчиков, знакомых с объектно-ориентированным программированием.
Встроенные классы представлений.
Django предоставляет различные классы представлений, которые можно использовать для упрощения разработки.
Вот некоторые из них:
1.
2.
3.
4.
5.
6.
7.
8.
Все эти классы представлений отличаются друг от друга своими функциями и способами применения. Они позволяют упростить и ускорить процесс разработки, предоставляя готовые решения для распространенных задач.
Теории много, но без неё было никак. В следующей части начнём переделывать представления из функциональных в классовые.
При использования классов-представлений можно определить методы, такие как
get(), post(), которые обрабатывают соответствующие типы запросов. В функциональном представлении, это повлекло бы за собой цепочку if-elif условий для обработки нужного типа запроса в представлении.Различия между функциональными и классовыми представлениями:
1. Структура кода: В функциональных представлениях код разбит на функции, которые выполняют определенные действия. В классовых представлениях код организован в виде классов, которые содержат методы для обработки запросов.
2. Наследование: В классовых представлениях можно использовать наследование, что позволяет переиспользовать код и добавлять новую функциональность. В функциональных представлениях такая возможность отсутствует.
3. Расширяемость: Классовые представления позволяют легко добавлять новые методы и функциональность без изменения основного кода. В функциональных представлениях это может быть сложнее.
4. Миксины: Классовые представления поддерживают использование миксинов, которые представляют собой классы с определенными методами, которые можно добавить к основному классу представления для расширения его функциональности.
5. Читаемость кода: Классовые представления могут быть более читаемыми и понятными, особенно для разработчиков, знакомых с объектно-ориентированным программированием.
Встроенные классы представлений.
Django предоставляет различные классы представлений, которые можно использовать для упрощения разработки.
Вот некоторые из них:
1.
View: Это самый базовый класс представления в Django. Он обрабатывает связывание представления с URL, диспетчеризацию методов HTTP и другие общие функции. Все другие классы представлений Django наследуются от этого класса.2.
TemplateView: Этот класс представления используется, когда вам нужно просто отобразить страницу, которая не требует никакой дополнительной логики. Он автоматически рендерит указанный шаблон.3.
ListView: Это класс представления, который используется для отображения списка объектов. Он автоматически предоставляет контекст для шаблона, который содержит список объектов.4.
DetailView: Этот класс представления используется для отображения деталей конкретного объекта. Он автоматически предоставляет контекст для шаблона, который содержит объект.5.
CreateView, UpdateView, DeleteView: Эти классы представлений используются для создания, обновления и удаления объектов соответственно. Они автоматически предоставляют форму для ввода данных и обрабатывают POST-запросы для создания, обновления или удаления объектов.6.
FormView: Этот класс представления используется для отображения и обработки форм. Он автоматически предоставляет форму для ввода данных и обрабатывает POST-запросы.7.
RedirectView: Этот класс представления используется для перенаправления на другой URL.8.
DateDetailView, YearArchiveView, MonthArchiveView, DayArchiveView, TodayArchiveView: Эти классы представлений предназначены для отображения архивов объектов, отсортированных по датам.Все эти классы представлений отличаются друг от друга своими функциями и способами применения. Они позволяют упростить и ускорить процесс разработки, предоставляя готовые решения для распространенных задач.
Теории много, но без неё было никак. В следующей части начнём переделывать представления из функциональных в классовые.
🔥3
Код на салфетке
Приветствую! В длинных постах можно запутаться поэтому, собираю воедино всё, что есть на данный момент. Оглавления Для удобства навигации есть посты с оглавлениями по темам: Список всех постов по Django Список всех постов по AIOgram3 Список всех постов…
Информация для новоприбывших =)
Django 27.2 Представления на основе классов - Практика
Разобравшись для чего нужны функциональные и классовые представления, перейдём к практике по преобразованию представлений.
На данный момент у меня в проекте 4 представления, а именно:
- Главная страница
- Страница категории
- Страница поста
- Страница тега
Откроем файлы
Разобравшись для чего нужны функциональные и классовые представления, перейдём к практике по преобразованию представлений.
На данный момент у меня в проекте 4 представления, а именно:
- Главная страница
- Страница категории
- Страница поста
- Страница тега
Откроем файлы
views.py и urls.py.Представление главной страницы.
Вот так представление выглядит на данный момент:
Для того, чтобы переписать это в классовый вид, создадим новый класс
В классе пропишем единственное поле -
Также в классе будет всего один метод -
В теле метода, получим из родительского класса экземпляр контекста, представляющий собой словарь.
Дале пропишем две строки, где по ключам добавим данные контекста. Ключом будет переменная для использования в шаблоне, а значением данные.
В конце делаем возврат контекста.
Код:
URL-паттерн главной страницы.
У нас уже есть паттерн для главной страницы:
Сейчас представление выглядит так:
Создадим класс
В данном классе будет 3 поля, 2 переопределённых метода и один собственный метод.
Поля класса.
Первое поле
Второе поле, как и в предыдущем классе -
В третьем поле
Собственный метод.
В нашем классе мы создадим собственный метод
Это сделано для избегания повторных обращений к базе данных, для получения объекта текущей категории в переопределённых методах.
Логика проста, мы не задали поле класса для хранения объекта категории. При обращении к методу, проиводится проверка, существует или нет поле с именем
Если поле существует, возвращается его значение.
Если поле не существует, то оно создаётся и в него мы присваиемаем полученные из БД данные.
Вот так представление выглядит на данный момент:
def index(request):В функции мы получаем список категорий и список последних постов, добавляем их в контекст и возвращаем рендер шаблона с данными.
categories_list = models.CategoryModel.objects.all()
latest_posts = models.PostModel.post_manager.latest_posts()
context = {
'categories_list': categories_list,
'latest_posts': latest_posts,
}
return render(request,
'blog/index.html',
context)
Для того, чтобы переписать это в классовый вид, создадим новый класс
IndexView и унаследуем его от TemplateView.В классе пропишем единственное поле -
template_name и присвоим ему строку с путём до шаблона главной страницы.Также в классе будет всего один метод -
get_context_data, принимающий self и набор именованных аргументов **kwargs.В теле метода, получим из родительского класса экземпляр контекста, представляющий собой словарь.
Дале пропишем две строки, где по ключам добавим данные контекста. Ключом будет переменная для использования в шаблоне, а значением данные.
В конце делаем возврат контекста.
Код:
from django.views.generic import TemplateViewВ данном случае, нам не нужно беспокоится о рендере шаблона и прочем. Всё это прописано в родительском классе, он при обращении к странице, получит данные из переопределённого метода и вернёт пользователю шаблон.
class IndexView(TemplateView):
template_name = 'blog/index.html'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['categories_list'] = models.CategoryModel.objects.all()
context['latest_posts'] = models.PostModel.post_manager.latest_posts()
return context
URL-паттерн главной страницы.
У нас уже есть паттерн для главной страницы:
path('', views.index, name='index'),
Он ведёт на функцию, для класса, его необходимо слегка изменить, а именно поменять имя функции index на имя класса IndexView и добавить обращение к методу as_view(), сообщающему, что мы обращаемся к классу-представлению.path('', views.IndexView.as_view(), name='index'),
Представление страницы категории.Сейчас представление выглядит так:
def category_page(request, category_slug):Для вывода списка постов на странице категории будем использовать
category = models.CategoryModel.objects.get(slug=category_slug)
descendant_categories = category.get_descendants(include_self=True)
posts = models.PostModel.objects.filter(category__in=descendant_categories)
categories_list = models.CategoryModel.get_children(self=category)
context = {
'category': category,
'posts': posts,
'categories_list': categories_list,
}
return render(request,
'blog/category_page.html',
context)
ListView.Создадим класс
CategoryPageView, который наследует `ListView`.В данном классе будет 3 поля, 2 переопределённых метода и один собственный метод.
Поля класса.
Первое поле
model, в нём мы передаём ссылку на модель, с которой будет представление. В нашем случае это модель поста.Второе поле, как и в предыдущем классе -
template_name.В третьем поле
context_object_name, мы определяем то, как будет называться переменная к которой мы обращаемся в шаблоне, у нас это - posts.Собственный метод.
В нашем классе мы создадим собственный метод
get_category, возвращающий объект текущей категории.Это сделано для избегания повторных обращений к базе данных, для получения объекта текущей категории в переопределённых методах.
Логика проста, мы не задали поле класса для хранения объекта категории. При обращении к методу, проиводится проверка, существует или нет поле с именем
category.Если поле существует, возвращается его значение.
Если поле не существует, то оно создаётся и в него мы присваиемаем полученные из БД данные.
Обратите внимание, PyCharm и возможно другие IDE будут сигнализировать, что в классе не задано поле category, игнорируем сообщение, поскольку именно в этом и смысл.
Переопределённые методы.
В предыдущем классе, мы переопределили только один метод
В методе добавим в контекст объект текущей категории и список подкатегорий.
Вторым переопределённым методом, будет метод
Код.
Сейчас представление выглядит так:
Создадим класс
Переопределим метод
В этом методе мы будем получать объект текущего поста и увеличивать счётчик просмотров на 1.
Метод будет вызываться автоматически при открытии поста.
Код.
Последнее, четвёртое представление. Сейчас оно такое:
Создаём класс
В классе прописываем три поля, как в предыдущие два раза.
Переопределяем метод
Переопределяем метод
Переопределённые методы.
В предыдущем классе, мы переопределили только один метод
get_context_data, переопределим его и в этом классе.В методе добавим в контекст объект текущей категории и список подкатегорий.
Вторым переопределённым методом, будет метод
get_queryset, необходимый для создания списка объектов, в нашем случае постов относящихся к этой и вложенным категориям. Об этом я подробно рассказывал в посте про создание представления страницы категории.Код.
from django.views.generic import ListViewПо аналогии с предыдущим классом, измените URL-паттерн.
class CategoryPageView(ListView):
model = models.PostModel
template_name = 'blog/category_page.html'
context_object_name = 'posts'
def get_queryset(self):
category = self.get_category()
descendant_categories = category.get_descendants(include_self=True)
return models.PostModel.objects.filter(category__in=descendant_categories)
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
category = self.get_category()
context['category'] = category
context['categories_list'] = models.CategoryModel.get_children(self=category)
return context
def get_category(self):
if not hasattr(self, 'category'):
self.category = models.CategoryModel.objects.get(slug=self.kwargs['category_slug'])
return self.category
path('category/<slug:category_slug>/', views.CategoryPageView.as_view(), name='category_page'),
Представление страницы поста.Сейчас представление выглядит так:
def post_page(request, category_slug, slug):Для классового представления страницы поста будем использовать
post = get_object_or_404(models.PostModel, slug=slug)
post.views += 1
post.save()
context = {
'post': post,
}
return render(request,
'blog/post_page.html',
context)
DetailView.Создадим класс
PostPageView, наследующий DetailView и пропишем такие же как в классе страницы категории, поля, а именно - model, template_name и context_object_name.Переопределим метод
get_object.В этом методе мы будем получать объект текущего поста и увеличивать счётчик просмотров на 1.
Метод будет вызываться автоматически при открытии поста.
Код.
from django.views.generic import DetailViewИ изменим URL-паттерн:
class PostPageView(DetailView):
model = models.PostModel
template_name = 'blog/post_page.html'
context_object_name = 'post'
def get_object(self, queryset=None):
obj = super().get_object(queryset=queryset)
obj.views += 1
obj.save()
return obj
path('post/<slug:category_slug>/<slug:slug>/', views.PostPageView.as_view(), name='post_page'),
Представление страницы тега.Последнее, четвёртое представление. Сейчас оно такое:
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)
Создаём класс
TagPageView, унаследованный от ListView.В классе прописываем три поля, как в предыдущие два раза.
Переопределяем метод
get_queryset, возвращающий посты относящиеся к текущему тегу.Переопределяем метод
get_context_data, добавляя в контекст объект текущего тега.