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

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

Реклама и взаимопиар: @Murzyev1995
Сотрудничество и др.: @proDreams
Download Telegram
Что выведет код с изображения ниже?
Anonymous Quiz
14%
Class One value
41%
Class Two value
24%
TypeError
21%
Ничего из перечисленного выше
Что выведет этот код? №5
Отдохнули от задачек за каникулы? Это видно по вашим ответам на вчерашнюю задачу.

Ключ к решению задачи заключается в понимании того, как работает присваивание ключа в Python-словаре, а также специфики хэширования объектов пользовательских классов.

В викторине приняли участие 21 человек. Правильных ответов было 9, это 43%! Правельный ответ самый популярный, праздники пошли на пользу🙂. Второй по популярности ответ - TypeError, за него проголосовало 7 человек.


Код задачи:
class MyClass:
def __repr__(self):
return "Class One"


class MyClassTwo:
def __repr__(self):
return "Class Two"


a = MyClass()

dct = {a: "value"}

a.__class__ = MyClassTwo

print(a, dct[a])



Структура задачи.
В самом начале мы создаём два класса: MyClass и MyClassTwo.

В обоих классах прописываем dunder-метод` repr`, возвращающий строку текста с названием класса.

Далее создаем экземпляр класса MyClass и записываем его в переменную a.

В переменной dct создаём словарь, где ключом будет содержимое переменной a (то есть экземпляр класса MyClass), а значением строка `"value".

Затем, обратившись к атрибуту __class__ объекта в переменной a, мы заменяем имя класса на MyClassTwo, меняя тем самым и класс объекта.

Выводим на печать значение переменной a и значение по ключу переменной a.


Так почему мы получили в ответе Class Two value?
Первое, чему можно было бы удивиться, так это тому факту, что изменяемый объект (а объекты пользовательских классов по умолчанию изменяемы) можно использовать в качестве ключа в словаре Python. На самом деле к ключам в словарях применяется требование о хэшируемости, а не о неизменяемости объекта. Большинство встроенных неизменяемых типов данных в Python хэшируемы, отсюда и путаница. Объекты пользовательских классов хэшируемы по умолчанию поэтому вполне могут быть использованы в качестве ключей в словарях.

Второй неочевидный момент связан с тем, что мы "на лету" меняем класс объекта, записанного в переменную a, но это никак не нарушает возможности обратиться к значению, которое записано в словарь по ключу, находящемуся в a. Как же так? У нас изменился объект в ключе, но по нему всё ещё можно вызвать привязанное к изначальному объекту значение? Получается, что так. И это также связано с особенностями хэширования объектов пользовательских классов. Дело в том, что хэширование объектов пользовательских классов происходит по id(), которое - сюрприз - остаётся прежним, несмотря на изменеине класса объекта с одного пользовательского на другой. В этом легко убедиться, запустив следующий код:

class MyClass:
def __repr__(self):
return "Class One"


class MyClassTwo:
def __repr__(self):
return "Class Two"


a = MyClass()

print(id(a)) # 4323000272

a.__class__ = MyClassTwo

print(id(a)) # 4323000272



Таким образом, id объекта не меняется при изменении его класса через атрибут __class__, следовательно, и хэш остаётся тем же самым. А, значит, и ключ в словаре остаётся неизменным. Живите с этим...
🔥6👍1👏1
Основы ООП на Python. ч. 1
Автор: Андрей Лебедев

В декабре мы проводили опрос, чтобы узнать, какую тему о Python наши читатели хотели бы разобрать в следующем посте рубрики “Код в мешке”. Выбор большинства пал на ООП (объектно-ориентированное программирование): так ответило 36% проголосовавших. Что ж, ваша воля для нас – закон.
🔥5
Python полон парадоксов. С одной стороны, код в Python совсем необязательно должен быть выполнен в методологии ООП. Создавая телеграмм-бота, например, или простенький скрипт для парсинга данных с какого-нибудь сайта, вполне естественно обходиться без ООП. С другой стороны, как вы уже, наверное, неоднократно слышали, всё в Python является объектом, то есть экземпляром какого-то класса. Это касается буквально всего: строк, целых чисел, списков, функций и т.д. Таким образом, если вы пишете код на Python, вы автоматически используете ООП. Поэтому даже если вы планируете до конца своих дней писать код, например, в структурной парадигме, изучить ООП всё равно стоит. Чем лучше вы будете его понимать, тем эффективнее вы будете работать с классами, написанными другими людьми.

Что такое ООП?

В учебниках или статьях вы найдёте примерно следующее определение ООП:
*️⃣ парадигма программирования, в центре которой данные и объекты, а не функции, как при процедурном подходе.
*️⃣ методология программирования, основанная на представлении программы в виде совокупности объектов, каждый из которых является экземпляром определённого класса, а классы образуют иерархию наследования.
*️⃣ парадигма разработки, в рамках которой все написанные программы состоят из объектов.
*️⃣ подход, при котором программа рассматривается как набор объектов, взаимодействующих друг с другом. У каждого есть свойства и поведение.

В центре любого определения находится понятие “объекта”, что едва ли удивит человека, который знает, как расшифровывается ООП. Где-то упоминаются классы, где-то – свойства и поведение объектов, но в целом разговор обычно строится вокруг классов (неких шаблонов) и экземпляров этих классов (объектов, которые на основании этих шаблонов создаются). Утверждается, что объектно-ориентированное мышление вообще присуще человеку: мы, мол, видим мир как совокупность объектов, которые как-то друг с другом взаимодействуют. Даже человеческие языки устроены таким образом, чтобы описывать мир в категориях объектов, которые обладают какими-то качествами и что-то делают. В некоторых случаях вспоминают даже древнегреческих философов, а именно Платона с его миром идей и миром вещей. В первом существует, например, идея кошки (класс), некий образ, по подобию которого созданы все кошки из мира вещей (объекты).

Всё это справедливо и всё это важно понимать, но я предлагаю начать с чего-нибудь попроще. Всё программирование, если предельно упростить, – это разговор про данные и их последовательную обработку. А ООП – это способ хранения данных и действий с ними в одном месте. Что это означает, давайте рассмотрим на примере:


class Student:

def __init__(self, name=""):
self.name = name

def say_hello(self):
print(f"Привет, я {self.name}!")


Здесь всего один элемент информации (атрибут класса) - имя ученика, а также всего одно действие (метод) - поздороваться. Информация об ученике и его функционал содержится в классе Student. И это очень удобно по целому ряду причин:
*️⃣ Код легче писать. Нужная информация и действия хранятся в классе. Их легко снова и снова использовать, создавая экземпляры.
*️⃣ Код легче читать. Если представить, что в нашем классе больше одного метода, то и без дополнительных объяснений будет понятно, что происходит в следующем коде:


stan = Student(“Стэн”)

stan.say_hello()
stan.do_homework()
stan.sing(“Hello people”)
stan.say_bye()


*️⃣ Код легче обновлять. Если нам понадобится, чтобы все созданные нами студенты говорили “Добрый день” вместо “Привет”, нам достаточно изменить код в одном месте: в классе Student.
*️⃣ Код легче разрабатывать в команде. Если код распределен по классам и объектам, то над каждым из них может работать один человек, а дальше результаты работы всех можно объединять.
🔥5
*️⃣ Код можно использовать в новых проектах. Если вся информация и действия компактно собраны в классе, то его можно использовать в других проектах, создавая соответствующие объекты уже в них.

Что такое self?

В примере выше в двух методах (то есть функциях внутри) класса Student в качестве аргумента используется объект self. Редко кто в подробностях рассказывает о том, что это за объект. Чаще говорят о том, что он позволяет делать: он даёт доступ к атрибутам (элементам информации) класса из любого места внутри самого этого класса. В нашем примере с классом Student мы в момент инициации (создания) объекта этого класса методом __init__ ввели атрибут self.name. Благодаря этому ниже – в методе say_hello, куда мы передали объект self, – мы смогли использовать этот же атрибут для того, чтобы ученик говорил приветствие и представлялся по имени.

Но что же такое self? Обычно говорят, что это ссылка на текущий экземпляр класса. Тот самый, который создаётся в момент инициализации. Вернёмся к нашему примеру с классом Student и воспользуемся приёмом, который знаком любому начинающему питонисту: в любой непонятной ситуации выводи всё в консоль print’ом!


class Student:

def __init__(self, name=""):
self.name = name
print(self) # <__main__.Student object at 0x1062c7790>

def say_hello(self):
print(f"Привет, я {self.name}!")


stan = Student("Стэн")
print(stan) # <__main__.Student object at 0x1062c7790>


Мы добавили два print’а:
*️⃣ вывод объекта self в методе __init__ сразу после записи имени ученика в атрибут self.name,
*️⃣ вывод экземпляра класса Student сразу после его создания и записи в переменную stan.

Что происходит в результате? В момент инициализации объекта класса Student, который мы записываем в переменную stan, на печать выводится объект self. Из записи <__main__.Student object at 0x1062c7790> видно, что этот объект класса Student, находящийся в модуле main, хранится в ячейке памяти за номером 0x1062c7790. Дальше на печать выводится объект в переменной stan, и мы видим, что это тот же самый объект, хранящийся в той же ячейке. Именно это и означает формулировка “ссылка на текущий экземпляр класса”.

Что еще важно знать про self?

*️⃣ Вместо self можно использовать любое другое название для переменной текущего объекта, но выбранного имени необходимо последовательного придерживаться в коде класса:


class Student:

def __init__(child, name=""):
self.name = name

def say_hello(child):
print(f"Привет, я {child.name}!")


При этом стоит помнить, что классическим и общепринятым вариантом всё же считается self. Об этом вам будут стараться напоминать даже некоторые IDE.

*️⃣ Есть способ увидеть все атрибуты, записанные в self. Для этого нужно обратиться к словарю __dict__, который ассоциирован с self:


class Student:

def __init__(self, name="", age=0):
self.name = name
self.age = age
print(self.__dict__)

def say_hello(self):
print(f"Привет, я {self.name}!")


stan = Student("Стэн", 8)

# {'name': 'Стэн', 'age': 8}


Что такое __init__()?

Последний незнакомый элемент синтаксиса, который появился в нашем первом примере, - это метод __init__, известный также как конструктор класса. Если упростить, то он служит для записи передаваемых при создании объекта данных в атрибуты объекта self. Так, например, мы передавали имя ученика при создании экземпляра класса Student.
🔥5
Может ли класс существовать без __init__? Да, прекрасно может. Каждый раз, когда создаётся новый экземпляр класса, Python ищет в классе метод __init__. Если он его находит, то метод запускается автоматически. Если нет, то никакие атрибуты в self не записываются. Именно поэтому важно не допускать ошибок при написании данного метода. Если, например, указать _init__ (с одним подчеркиванием) или __int__ (без второй “i”), передав в них аргументы, они скорее всего никогда не попадут в self, потому что автоматически метод при инициализации объекта вызван не будет. Вызвать же написанный с ошибкой метод вручную разработчик едва ли догадается.

Из всего указанного выше следует, что в качестве конструктора класса можно было бы использовать и созданный вручную метод. Разница будет лишь в том, что в отличие от __init__ он не будет вызван автоматически при создании экземпляра класса. Его нужно будет явным образом вызвать в коде, передав аргументы для записи в атрибуты уже в него:


class Student:

def initialize(self, name=""):
self.name = name

def say_hello(self):
print(f"Привет, я {self.name}!")


stan = Student()
stan.initialize("Стэн")
stan.say_hello() # Привет, я Стэн!


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

В следующий раз мы продолжим разговор о методах классов.

Пост на сайте
Поддержать проект

#Python #ООП #код_в_мешке #объект #атрибут #класс #init #self #метод
🔥9👍1
Приветствую!

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


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

"Сайт на Django"
"Telegram-бот на AIOgram3"
"Применение Docker"
"Полезные инструменты"
"Вести с полей стажировки."
"Некий проект"
"Код в мешке"
"Boosty эксклюзив"


Ресурсы канала:

Уютный и немного безумный чат канала.
Бот с материалами к постам
Сайт со всеми постами
Канал в Dzen
Сообщество в VK


Поддержка.

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

Также поддержать канал можно на Boosty.

Или внеся сайт в исключения вашего блокировщика рекламы.
🔥5👍1
Приветствую, друзья!

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

Фильм: Искусственный разум

Год: 2001

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

https://www.sspoisk.ru/film/594/?utm_referrer=www.google.com

Приятного просмотра)
🔥4
Что выведет код с изображения ниже?
Final Results
21%
IndexError: list index out of range
66%
[]
3%
[10]
10%
[8, 10]
🤯2👍1😱1
Что выведет этот код? №6
🤯1😱1
Вчера была опубликована очередная интересная задача из рубрики "Что выведет данный код?". Задача вам понравилась, судя по вашей активности в комментариях. Сама задача не очень сложная, основная её сложность в понимании того, как работает цикл for. Зная принцип его работы, отследить процесс можно прямо в голове, не запуская код.

В викторине приняли участие 29 человек. Верных ответов было ... всего 3, а если убрать редакцию, то остаётся вовсе один. Кто же ты, единственный верный? Пришли скрин верного ответа в чат, впишем тебя в пост! Лидирующим вариантом стал второй, с пустым списком, а на втором месте ошибка выхода за границы списка.


Код задачи:
def delete_starting_evens(lst):
for _ in lst:
if lst[0] % 2 == 0:
lst.pop(0)
else:
break
return lst


my_list = [2, 6, 8, 10]

print(delete_starting_evens(my_list))



Структура задачи:
Сперва мы объявляем переменную my_list, записав в неё список с целыми числами.

Затем вызываем print, передавая в него функцию delete_starting_evens со списком в аргументе.

В функции проходим циклом по элементам и, если первый элемент - чётное число, то с помощью метода pop убираем его из списка. Если же первое число в списке нечётное, то останавливаем цикл. В конце возвращаем список.

Так почему результат именно [8, 10], а не какой-нибудь другой?
Всё дело в устройстве работы цикла for, работу которого достаточно трудно порой отследить в голове, не вызывая print'ов. Особенно сложно приходится, когда список, по которому проходится цикл, сокращается в процессе работы цикла.

Цикл for работает "с начала и до победного", т.е., получив на вход список, он будет работать до тех пор, пока его не прервут или пока список не закончится.

Небольшое пояснение касательно переменной _. В питоне, если итерируемое значение цикла не используется, принято заменять его на символ нижнего подчёркивания - _. Однако при желании к этому символу также можно получить доступ как к любой другой переменной.


Рассмотрим полный цикл работы функции:
1. Функция получает на вход список [2, 6, 8, 10].
2. Значение переменной _ = 2 (нулевой элемент текущего списка). Список сейчас такой: [>2, 6, 8, 10]. > - указание на каком элементе находится цикл.
3. В блоке if мы проверяем чётный или нет 0-й элемент списка. Он чётный, удаляем его.
4. Значение переменной _ = 8 (первый элемент текущего цикла). Список сейчас такой: [6, >8, 10].
5. Снова проверяем является ли нулевой элемент чётным. Является, удаляем его.
6. Значение переменной _ = ? (Второй элемент текущего цикла). Список сейчас такой: [8, 10, >?]. Как видим, сейчас значение переменной _ выходит за границы списка в его текущем виде. Значит, мы дошли до конца.
7. Цикл for заканчивает свою работу не заходя внутрь.
8. Возвращаем список.
9. Выводим его на экран.


Заключение.
В данной задаче показан пример того, что будет если изменять размер списка ДО текущего положения счётчика. Он достаточно безобидный. Однако, если изменять размер списка ПОСЛЕ счётчика, могут возникнуть проблемы, особенно, если обращаться к стоящим после счётчика элементам, т.к. после изменения списка, он перестраивается и порядок индексации изменяется.
🔥7🤯2❤‍🔥1
Первый созвон...
Автор: Некий Вестник Сплетен

Время шло, и нужно было начинать работу, а с чего её начинать, никто не знал. Путём обсуждения в чате было решено, что нам нужен общий созвон. Удобное для большинства участников время решили выбрать путём голосования, постепенно сужая выбор предлагаемых вариантов. Таким образом созвон был назначен на субботу 28 октября 2023 года в 17-00.

Начали с обсуждения самой идеи проекта. Изначально вариантов было много, и все они были очень интересными (возможно, мы захотим реализовать в будущем и их). В обсуждении активно участвовала большая часть команды, из-за чего оно получилось очень живым. В итоге выбор пал на сервис поиска проектов или коллег для совместной работы (сайт - биржа фриланса).
😎3🔥2
Определившись с направлением проекта, мы приступили к подбору подходящего названия для проекта, название команды и аватарки для более удобного поиска чата в Telegram (всё общение в нашей команде проходит на созвонах и в чате тг).

Устроили голосование за название проекта. Выбирать предлагалось из следующих вариантов:
- DevMatch (Developer Match)
- ЯСделяль
- I try - You pay
- Command&Project hub
- KekProjekt
- iCommand
- iSearchCommand
- CommandHub

По итогам был выбран вариант DevMatch (Developer Match). Сперва хотели от него отказаться, так как такой сайт уже есть на зарубежном пространстве, но мы в РФ, что они нам сделают?

Следом запустили ещё два голосования: выбор аватарки нашего чата и название команды.

Варианты названий команд были самыми разными:
- Victims of Сourses
- Некий проект
- DevMatch Team
- Order or the Crooked Finger
- team of commanders
- little hard workers
- Команда Вечное сияние чистого разума
- Слабоумие и отвага

Выбрали название команды. Ввиду того, что чат для проекта, пока он не был обозначен, назывался "Некий проект", в итоге решили, что пусть так и остаётся.

Далее стали думать над составлением ТЗ.
Один из участников нашёл в интернете образец-черновик технического задания, затем Андрей (BackEnd) скинул еще один вариант и мы начали работу над ТЗ, опираясь на эти файлы как на шаблоны.

Были внесены первые корректировки в ТЗ. На начальном этапе в основном этим занимались Иван и Антон.

Особо много там не написали, поскольку опыта в этом деле у всех было мало.

Составили несколько таблиц с навыками и знаниями участников, направлением их работы, а так же основную с настоящими именами, поскольку большая часть скрыта за никами. Заодно и познакомились.

Оставался ещё один важный вопрос: в каком сервисе распределять задачи по участникам?

Евгением (UX/UI) было предложено использование сервиса YouGile для распределения задач. На нём мы и остановились. Пришлось изучать новые инструменты работы.

Итак, работа закипела.

Пост на сайте
Поддержать проект

#код_на_салфетке #техническое_задание #созвон #некий_проект #биржа_фриланса #название_проекта #командная_работа
🔥4😎1
Приветствую.

По постам "Некого Вестника" вы в курсе, что у нас есть "Некий Проект". Если простыми словами, то это биржа фриланса с упором на командную работу.

Мы ещё достаточно далеки хотя бы для MVP, поскольку особых сроков и дедлайнов у нас нет, но работа идёт.

Сейчас нам в команду требуются фронтэнд разработчики знакомые с Vue3.

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

Если вы хотите применить свои знания на практике и поработать в команде таких же новичков, то напишите мне @proDreams
🎉5
Прошёл ещё месяц учебы, вернее не учёбы, а её завершения.

Настало время "отчётного" поста на Plkabu.

https://pikabu.ru/story/obuchenie_vosemnadtsatyiy_mesyats_posledniy_11058755?utm_source=linkshare&utm_medium=sharing

Расчехляйте лайкомёты 😊
🔥7
Django 40. Собственные страницы ошибок
Автор: Иван Ашихмин

Ошибки на сайте случаются постоянно, но далеко не все из них происходят по вине программиста. Самая знаменитая ошибка – 404 Not Found – относится к пользовательским ошибкам, когда был совершён переход на несуществующую страницу. Ещё одна известная ошибка – 500 Internal Server Error – относится к ошибкам на стороне сервера. Это означает, что сервер не справился с какой-то задачей.

Всё это называется "Кодом состояния HTTP" или по простому "HTTP статус кодом".

Всего их пять видов:
1. 1xx - информационные.
2. 2xx - успешные.
3. 3xx - перенаправления.
4. 4xx - ошибки клиента.
5. 5xx - ошибки сервера.

Полный список кодов с описанием доступен в википедии: https://ru.wikipedia.org/wiki/Список_кодов_состояния_HTTP

Нас интересуют 4xx и 5xx статус коды, проще говоря – ошибки.
🔥4
Мы с вами сделаем страницы отображающиеся при следующих ошибках:
- 400 Bad Request – когда был отправлен неправильный запрос или данные.
- 403 Forbidden – когда пользователь пытается получить доступ к страницам сайта, на просмотр которых у него нет разрешения.
- 404 Not Found – когда пользователь переходит на несуществующую страницу.
- 500 Internal Server Error – когда на стороне сервера что-то пошло не так и поднялась необработанная ошибка.


Утилитарное приложение utils_app.
Для обработки ошибок нам необходимо написать обработчики. Дабы не писать их в основных приложениях, создадим новое utils_app.
Для этого выполним команду: python manage.py startapp utils_app.

Не забудьте сразу добавить новое приложение в INSTALLED_APPS


Обработчики ошибок.
Нам необходимо написать четыре простейшие функции, которые будут вызываться при возникновении определённой ошибки.

В директории приложения создадим файл exception_handlers.py.

Создадим четыре функции:
- bad_request_handler - для обработки 400-й ошибки.
- permission_denied_handler - для обработки 403-й ошибки.
- page_not_found_handler - для обработки 404-й ошибки.
- server_error_handler - для обработки 500-й ошибки.

Каждая функция принимает два аргумента request и exception. Обратите внимание, что аргумент exception не всегда передаётся в обработчик, по этому устанавливаем ему значение по умолчанию None.

В каждой функции возвращаем работу функции render, передавая в аргументах request, путь до файла шаблона и статус-код ошибки.


Код функций:
from django.shortcuts import render  
from rest_framework import status


def bad_request_handler(request, exception=None):
return render(request, "utils_app/400.html", status=status.HTTP_400_BAD_REQUEST)


def permission_denied_handler(request, exception=None):
return render(request, "utils_app/403.html", status=status.HTTP_403_FORBIDDEN)


def page_not_found_handler(request, exception=None):
return render(request, "utils_app/404.html", status=status.HTTP_404_NOT_FOUND)


def server_error_handler(request, exception=None):
return render(request, "utils_app/500.html", status=status.HTTP_500_INTERNAL_SERVER_ERROR)



Шаблон страницы с ошибкой.
Нам нужно четыре шаблона. Создадим в директории с шаблонами новую директорию для приложения utils_app и в ней файлы шаблонов.

У меня четыре шаблона. Все четыре одинаковые, за исключением текста, поэтому покажу пример только одного шаблона:
{% extends "blog/base.html" %}
{% block title %}404 - страница не найдена!{% endblock %}

{% block content %}
<div class="d-flex align-items-center justify-content-center vh-100">
<div class="text-center">
<h1 class="display-1 fw-bold">404</h1>
<p class="fs-3"><span class="text-danger">Ой!</span> Страница не найдена.</p>
<p class="lead">
Запрашиваемая вами страница не найдена.
</p>
<a href="{% url 'blog:index' %}" class="btn btn-primary my-btn">Вернуться на главную</a>
</div>
</div>
{% endblock %}


Выводим текст соответствующий статус-коду.


Подключение обработчиков.
Осталось подключить обработчики. Для этого откроем главный файл urls.py, расположенный в директории проекта рядом с файлом settings.py.
🔥5
В нём в конце файла добавляем четыре переменные. Значением переменных будет строка вида "название_приложения.файл_с_обработчиками.название_функции_обработчика".

handler400 = "utils_app.exception_handlers.bad_request_handler"  
handler403 = "utils_app.exception_handlers.permission_denied_handler"
handler404 = "utils_app.exception_handlers.page_not_found_handler"
handler500 = "utils_app.exception_handlers.server_error_handler"


Обратите внимание! Чтобы собственные страницы ошибок заработали, параметр DEBUG в файле settings.py должен быть установлен в False!


Заключение.
Вот таким вот простым и нехитрым способом можно сделать собственные страницы ошибок в Django.

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

Пост на сайте
Поддержать проект

#Python #Django #гайды #Bad_Request #страницы_ошибок #обработчики_ошибок #Forbidden #Internal_Server_Error #Not_Found
🔥8👍1
Что выведет код с изображения ниже?
Anonymous Quiz
16%
3
8%
2
45%
[0, 1, 2]
31%
TypeError
👍4🤯3