Почати тут Вивчити Python Більше Пошук єднатися При - Серія безкоштовних розсилок - � Трюки на Python � Електронна пошта... Get Python Tricks " Створіть соціальну мережу за допомогою Django - 🔒 Без спаму. Відпишіться в будь-який час. Частина 1 Позначит by Martin Breuss Jan 03, 2022 10 Comments django intermediate web-dev Переглянути и як Керовані шляхи навчання теми завершене flask front-end gamedev Зміст Базовий Середній Просунутий gui Tweet Демонстрація Поділитися машинне навчання Email Огляд проекту бази даних спільноти найкращих проекти api python Профілі для практик Зміст з'єднань між data-science devops django docker Довідка інструменти користувачами Демонстрація Текстовий вміст Загальни web-dev тестування Передумови й огляд проекту web-scraping Крок 1: Створіть базовий Передум проект ови Створення віртуального середовища та встановлення Django Створення проекту та програми Django Налаштування інтерфейсу адміністратора Django Створення користувачів для вашого додатку Видалит и реКрок кламу 2: Розширення моделі користувача Django Крок 1: Створіть базовий проект Крок 2: Розширте модель користувача Django Крок 3: Реалізуйте висновок хука після збереження Створіть модельпрофілю Відображення інформації про профіль на сторінці адміністратора користувача Крок 3: Реалізація хука після збереження Наступні кроки для вашої основної соціальної Координуйте користувачів і профілі за допомогою сигналу Додавання функціональності завдяки розробці, керованій помилками Рефакторинг коду за допомогою декоратора мережі за допомогою Django Позначити як завершене Підтвердьте автоматичну асоціацію у висновку адміністратора Наступні кроки для вашої базової соціальної мережі за допомогою Django Tweet Поділитися Email У цій серії з чотирьох частин ви створите соціальну мережу за допомогою Django, яку зможете продемонструвати у своєму портфоліо. Цей проект зміцнить ваше розуміння взаємовідносин між моделями Django і покаже, як використовувати форми, щоб користувачі могли взаємодіяти з вашим додатком і один з одним. Ви також дізнаєтесь, як зробити ваш сайт гарним за допомогою фреймворку CSS Bulma. У першій частині цієї серії уроків ви дізнаєтеся, як цезробити: Реалізація зв'язків "один-до-одного" та "багато-до-багатьох" між моделями Django Розширте модель користувача Django за допомогою користувацької моделі профілю Налаштуйте інтерфейс адміністратора Django Закінчивши першу частину цієї серії, ви перейдете до другої частини, де навчитеся інтегрувати Bulma для стилізації вашого додатку і реалізовувати інтерфейс і логіку, щоб ваші користувачі могли відстежувати і відстежувати один одного. Ви можете завантажити код першої Отримати вихідний код: Натисніть частини цього проекту, натиснувши тут, щоб отримати вихідний код, на посилання нижче і використати перейшовши до папки який ви можете для source_code_final/: створення соціальної мережі за допомогою Django. Демонстрація У цій серії з чотирьох частин ви створите невелику соціальну мережу, яка дозволяє користувачам публікувати короткі текстові повідомлення. Користувачі вашого додатку можуть підписатися на інших користувачів, щоб бачити їхні дописи, або відписатися від них, щоб не бачити їхніх дописів: Наприкінці цього циклу уроків ви також навчитеся використовувати CSSфреймворк Bulma, щоб надати вашому додатку зручний для користувача вигляд і зробити його вражаючою частиною вашого портфоліо веб-розробки, якою ви зможете з гордістю демонструвати. У першій частині цієї серії ви сплануєте проект, створите базовий веб-додаток Django і розширити вбудовану модель користувача за допомогою хука пост-збереження. Наприкінці цієї частини ви зможете створювати нових користувачів за допомогою інтерфейсу адміністратора Django, а ваш додаток автоматично створить профіль для кожного нового користувача і налаштує необхідне з'єднання: Реалізація бекенд-користувача закладає фундамент, який ви будете розвивати в наступних частинах. Видалити рекламу Огляд проекту У цьому розділі ви отримаєте чітке уявлення про те, що ви будете створювати і чому саме так. Ви також заглибитесь у взаємозв'язки між базами даних, які ви будете реалізовувати, і отримаєте повний план проекту, готовий до роботи. Коротше кажучи, ви виділите трохи часу на мозковий штурм ідеї вашого проекту. Після того, як ви розробите свій план, ви почнете практичні кроки з реалізації першої частини серії, яка присвячена моделям Django та їх взаємозв'язкам: Крок 1 Створіть базовий проект Крок 2 Розширення моделікористувача Django Крок 3 Реалізація хукапісля збереження Щоб отримати загальне уявлення про те, як ви будете працювати з усіма чотирма частинами цієї серії про створення соціальної мережі Django, ви можете розгорнути розгорнутий розділ нижче: Повні етапиреалізації проекту Показати/приховати Можливо, вам не терпиться почати програмувати, але перед початком роботи над будь-яким проектом з кодування корисно подумати про структуру того, що ви хочете створити. Ви можете використовувати псевдокод, письмові специфікації, схеми баз даних, каракулі в блокноті або будь-що, що здається доступним і допомагає вам думати. Не пропускайте цю частину! Це важливий крок для побудови будь-якого проекту. Час, який ви витратите на планування, значно скоротить час на реалізацію. Отже, що потрібно для соціальної мережі? У найпростішому випадку вам потрібні дві речі: 1. З'єднання між користувачами, які дозволяють людям спілкуватися один з одним 2. С творення та відображення контенту, щоб ваші користувачі могли створювати вихідні дані для перегляду підключеними користувачами Ви можете розглядати ці дві теми окремо одна від одної, але вони обидві вам знадобляться, щоб ваша соціальна мережа функціонувала належним чином. Профілі для з'єднань між користувачами У першій частині цієї серії уроків вам потрібно визначити, як ви можете дозволити користувачам підключатися і як це відображається на схемі бази даних. У цій частині ми зосередимося на з'єднаннях. Як реалізувати зв'язки в моделях Django? Спочатку ви запишете, як може виглядати базова версія цих зв'язків: 1. вашій соціальній мережі. У вас буде кілька користувачів у 2. В они повинні знати один про одного, щоб вирішити, за ким вони хочуть іти. У цьому проекті ви реалізуєте зв'язки між користувачами вашої соціальної мережі, дотримуючись кількох припущень, які розширюють два наріжні камені, згадані вище: Ваші користувачі зможуть відстежувати або не відстежувати інших користувачів. Якщо вони стежать за кимось, вони бачать контент цього користувача. Якщо ні, то не побачать. Ваші користувачі можуть стежити за людиною без того, щоб бути відстеженими у відповідь. Відносини у вашій соціальній мережі можуть бути асиметричними, тобто користувач може стежити за кимось і бачити їхній контент, але не бачити зворотного. Ваші користувачі повинні знати, хто існує, щоб вони знали, за ким вони можуть стежити. Користувачі також повинні знати, хто за ними стежить. У найпростішій формі вашого додатку користувачі не матимуть багато додаткових функцій. Ви не зможете заблокувати людей, а також не матимете можливості безпосередньо відповідати на контент, який розмістив хтось інший. По суті, ви можете уявити свою соціальну мережу як сховище коротких блогів або RSS-стрічок, на які користувачі можуть або підписатися, або ні. Це та реалізація, яку ви побудуєте в цій серії з чотирьох частин. Пізніше ви зможете розвинути цей фундамент, щоб зробити свою соціальну мережу більш специфічною і складною. Ви отримаєте необхідну вам функціональність, комбінуючи вбудовану модель користувача Django з користувацькою моделлю профілю, яка розширює стандартну модель користувача: На графіку вище ви бачите проект діаграми "сутність-зв'язок" (ER), яка показує, що кожен користувач матиме рівно один профіль, і що профілі можуть слідувати один за одним асиметрично. Ця схема не претендує на досконалість чи завершеність. Для вашого власного процесу, можливо, ви захочете накреслити на аркуші паперу щось дещо інше. Це мозковий штурм, тож використовуйте той формат, який вам найбільше підходить. Видалити рекламу Текстовий вміст Окрім налагодження зв'язків між користувачами, вашій платформі також потрібен спосіб, щоб користувачі могли створювати та обмінюватися контентом. Контент може бути будь-яким. Це можуть бути зображення, текст, відео, веб-комікси тощо. У цьому проекті ви створюєте соціальну мережу, яка повідомлення символів, з обробляє текстові обмеженою кількістю подібно до Twitter. Оскільки ви створюєте її за допомогою веб-фреймворку Django, вона матиме модну назву Dwitter. Вашій мережі Dwitter знадобиться модель для зберігання текстових повідомлень, які можуть створювати користувачі, і які ви називатимете твітами (dweets). Ви записуватимете лише три елементи інформації про кожен твіт: 1. Хто його написав 2. Про що йдетьсяу повідомленні 3. Існує Коли користувач написав його лише один зв'язок, який потрібно визначити для вашої моделі Dweet, - це її зв'язок з вбудованою моделлю User: ER-діаграма показує, як вбудована таблиця User з'єднується з таблицею Dweet за допомогою зв'язку "один-добагатьох". Цей тип зв'язку означає, що один користувач може мати багато твітів, і кожен твіт належить лише одному користувачеві. Ви також можете побачити різні поля в таблиці, які відповідають інформації, яку ви хочете зібрати про кожен твіт: 1. те, хто написав повідомлення користувач: містить інформацію про 2. повідомлення body: містить текстовий вміст 3. created_at: містить дату і час, коли користувач опублікував повідомлення Поле created_at на ER-діаграмі позначено сірим кольором, тому що ви не дозволите вашим користувачам редагувати його самостійно. Натомість, Django автоматично заповнюватиме це поле щоразу, коли користувач н а а д с и т и м е л нове повідомлення. Примітка: Жодна з моделей, які ви створили, не має багато полів, і це добре! Ви хочете створити базову реалізацію соціальної мережі, що відповідає критеріям, які ви визначили під час попереднього мозкового штурму. Ви завжди можете ускладнити її пізніше. Вам також знадобиться спосіб, за допомогою якого ваші користувачі зможуть створювати контент і переглядати ними та іншими контент, створений користувачами в їхній мережі. Для зручності користувачів вам доведеться виконати деякі з наведених нижче завдань для налаштування інтерфейсу: Надайте форму для надсилання контенту Створіть подання для обробки цих подань Створіть шаблони для відображення наявного контенту Надайте йому пристойного вигляду Більшість тем, які ви розглядатимете у цій серії, є загальними темами, які можна застосувати до багатьох веб-додатків Django. Можливо, ви вже знаєте, як робити деякі з них, але тут ви дізнаєтеся дослідити їх у контексті абсолютно нового проекту. І навіть якщо ви ще не стикалися з жодним із завдань, ви дізнаєтеся, як вирішувати кожну проблему одну за одною. Тепер, коли ви витратили трохи часу на мозковий штурм ідеї вашого проекту, ви можете готуватися до йогореалізації! Передумови Щоб завершити цю серію уроків, ви повинні добре засвоїти наступні поняття: Використання об'єктноорієнтованого програмування в Python Створення базового проекту Django Керування маршрутизацією та перенаправленнями, функціями перегляду, шаблонами, моделями та міграціями у Django Використання та налаштування інтерфейсу адміністратора Django Читання та запис HTML з атрибутами класів Якщо ви не володієте всіма цими знаннями перед початком цього підручника, нічого страшного! Ви можете дізнатися більше, просто розпочавши роботу. Ви завжди можете зупинитися і переглянути ресурси, на які ви посилаєтеся вище, якщо застрягнете. Оскільки ви будете використовувати Django для створення внутрішньої частини вашої соціальної мережі, вам потрібно бути знайомим з фреймворком Django, щоб отримати максимум користі з цієї серії. Якщо ви раніше не використовували Django, ви можете спробувати спочатку створити проект Django, який зосереджується на основах. Для гарного знайомства з Django ви можете створити додаток-портфоліо. Видалити рекламу Крок 1: Створіть базовий проект На цьому етапі ви знаєте, що будете створювати, і розумієте, які зв'язки між базами даних ви будете реалізовувати. Наприкінці цього кроку ви створите проект Django і відредагуєте інтерфейс адміністратора Django, щоб зробити його сфокусованим і мінімалістичним для користувача. Ви будете проходити кілька етапів один за одним: 1. встановіть Django Створіть віртуальне середовище та 2. Створення проекту та додаткуDjango 3. адміністратора Django Налаштування інтерфейсу 4. додатку Створюйте користувачів для вашого Перш ніж робити щось інше, ви створите віртуальне середовище і встановите Django. Створення віртуального середовища та встановлення Django Почніть зі створення нової кореневої папки Оболонка $ mkdir django-social $ cd django-social проекту, куди ви помістите всі файли, які ви створите під час роботи над цим проектом, а потім перейдіть до цієї папки: Перейшовши до батьківської папки, де ви будете розробляти свій проект, ви можете створити та активувати віртуальне середовище і встановити Django з Python Packaging Index (PyPI): Оболонка $ python3 -m venv venv --prompt=social $ source ./venv/bin/activate (соціальний) $ python -m pip install django==3.2.5 Ці команди створюють нове віртуальне середовище з назвою social, активують це середовище і встановлюють Django. Створення проекту та додаткуDjango Після завершення інсталяції ви можете розпочати новий проект Django з назвою social. Назва вашого проекту не обов'язково має збігатися з назвою вашого віртуального середовища, але так його буде легше запам'ятати. Після створення проекту Django створіть новий додаток Django під назвою dwitter, Оболонка (social) $ django-admin startproject social . який буде працювати разом з ним: (social) $ python Вам також потрібно зареєструвати ваш новий додаток dwitter в INSTALLED_APPS у manage.py startapp Python dwitter # social/settings.py # ... INSTALLED_APPS = [ "django.contrib. admin", "django.contrib. auth", файлі social/settings.py: "django.contrib. Додавання назви вашого додатку до цього contenttypes", списку дасть знати Django, що ви хочете "django.contrib. sessions", включити додаток до вашого проекту "django.contrib.messages", Django. Цей крок необхідний для того, "django.contrib.staticfiles", "двіттер", щоб редагування, які ви робите у dwitter, ] впливали на ваш проект. Примітка: Якщо вам потрібні детальніші інструкції, які допоможуть вам у Перш ніж продовжити роботу з цим підручником, переконайтеся, що ви це зробили: налаштуванні, ви можете дізнатися про те, 1. налаштувати Django. як середовище Активоване віртуальне 2. соціальний Новий проект Django під назвою 3. dwitter Додаток Django під назвою 4. dwitter, зареєстрований як додаток Файл settings.py вашого проекту з Якщо ви застрягли на якомусь з цих кроків, то ви знайдете всі необхідні кроки налаштування, детально описані у спеціальному підручнику з налаштування Django, посилання на який є вище. Видалити рекламу Налаштування інтерфейсу адміністратора Django Вбудований інтерфейс адміністратора Django є потужним інструментом для керування вашим додатком, і ви будете використовувати його для створення користувачів та керування ними у цьому підручнику. Примітка: У цьому підручнику ви не реалізовуватимете жодних функцій реєстрації для користувача. Втім, ви можете додати цю функціональність пізніше, слідуючи підручнику з керування користувачами Django. Щоб ваш досвід роботи з інтерфейсом адміністратора був зосереджений на найнеобхіднішому, ви можете застосувати деякі налаштування. Перш ніж це зробити, погляньте на стан за замовчуванням. Вам потрібно налаштуйте стандартну базу даних Оболонка (соціальний) $ python manage.py мігрувати (соціальний) $ python manage.py createsuperuser Ім'я Django SQLite і створіть користувача: admin суперкористувача, щоб ви могли увійти Адреса електронної пошти: до порталу адміністратора Django: admin@example.co m Пароль: Після виконання цих двох команд і Пароль (знову): Оболонка (соціальний) $ python manage.py runserver введення інформації для облікового запису суперкористувача, ви можете запустити сервер розробки Django: Перейдіть до URL-адреси /admin на вашому локальному хості через порт 8000 і увійдіть до порталу адміністратора: Ви можете бачити записи моделі за замовчуванням для груп і користувачів. Вони походять із вбудованих у Django програм автентифікації та керування користувачами. Не соромтеся озирнутися, якщо ви ще не знайомі з ними. Там є багато чого! Однак ви хочете, щоб цей проект був якомога ближче до основ, щоб зосередитися на модельних відносинах і змісті вашої соціальної мережі. Щоб спростити адміністрування, є кілька речей, які можна скоротити: 1. Ви не будете використовувати Групи Django, тому ви можете взагалі видалити їх з адміністративної панелі. 2. Н айпростіший спосіб створити користувача у Django - це передати лише ім'я користувача. Ви також можете вилучити всі інші поля з відображення моделі користувачів. Почніть з скасування реєстрації моделі "Група", що видалить цю модель з інтерфейсу адміністратора: Python # dwitter/admin.py from django.contrib import admin from django.contrib.auth.models import Group admin.site.unregister(Group) Щоб скасувати реєстрацію групи, спочатку імпортуйте її з django.contrib.auth.models. Потім, використовуйте .unregister(), щоб видалити його з адмін-панелі. Дослідити: Інтерфейс адміністратора Django Показати/приховати Далі ви зміните поля, що відображаються в адміністративній секції вбудованої моделі Python користувача Django. Для цього вам потрібно спочатку відреєструвати її, оскільки за замовчуванням ця модель є зареєстрованою. Потім ви можете перереєструвати модель користувача за замовчуванням, щоб обмежити поля, які повинні відображатися в адмінці Django. Для цього ви використовуєте власний клас UserAdmin: 1 # dwitter/admin.py 4 з django.contrib.auth.models 2 import User, Group 3 від django.contrib import admin 5 6 class UserAdmin(admin.ModelAdmin): 9 7 8 fields = model = User ["ім'я # Відображати тільки поле "ім'я користувача" користувача "] 12 admin.site.register 10 (User, UserAdmin) 11 admin.site.unregister(User) 13 admin.site.unregister(Група) Додавання цього коду до вашого файлу admin.py спрощує вміст, що відображається в адмінці сайту для користувача, а також інформацію, яку потрібно вводити при створенні нового користувача. Щоб нагадати, ось що ви робите в різних рядках коду: Рядок 4: Ви додаєте ще один імпорт, звідкиви отримуєте вбудовану модель користувача django.contrib.auth.models. Рядки з 6 по 9: Ви створюєте UserAdmin, користувацький клас на основі імпортованої моделі User. Рядок 9: Ви обмежуєте поля, що відображаються в інтерфейсі адміністратора, лише іменем користувача, чого достатньо для створення тестового користувача. Рядок 11: Ви скасовуєте реєстрацію моделі користувача, яка за замовчуванням зареєстрована в інтерфейсі адміністратора. Рядок 12: Ви знову реєструєте модель User, додатково передаючи кастомний UserAdmin клас, який ви створили, і який застосовує потрібні вам зміни. Якщо ви перейдете на сторінку огляду користувачів у розділі Головна → Автентифікація та авторизація → Користувачі, то ви помітите, що ваш адміністративний портал відображає набагато менше інформації, ніж раніше: З цими налаштуваннями інтерфейсу адміністратора Django ви можете швидко створювати тестових користувачів для вашого додатку, вказавши для них лише ім'я користувача. Видалити рекламу Створюйте користувачів для вашого додатку Перейдіть на Головну сторінку → Автентифікація та авторизація → Користувачі → Додати користувача, натиснувши на кнопку ДОДАТИ КОРИСТУВАЧА у верхньому правому куті інтерфейсу. Натиснувши на цю кнопку, ви потрапите на форму створення користувача за замовчуванням моделі користувача Django: Цей скорочений портал адміністратора Примітка: Використовуйте ці облікові записи тільки цілействорювати розробки. дозволяє вам для швидко Створення користувача без визначення додаткових тестових користувачів для вашої його пароля або будь-якої іншої соціальної мережі Django, коли вони вам додаткової інформації не є буде лише знадобляться, і вам потрібно безпечним. вказати для них ім'я користувача. Створіть двох додаткових користувачів за допомогою цього інтерфейсу. Ви можете дати їм будь-які імена, наприклад, аліса та боб. Після того, як ви створите додаткових користувачів, ви завершите початкове налаштування вашого проекту. На цьому етапі ви вже зробили кілька важливих речей: Ви створили проект Django під назвою social. Ви створили додаток Django під назвою dwitter. Ви очистили свій адміністративний портал, щоб зосередитися на основних функціях, які вам потрібні. Ви створили кілька користувачів для своєї соціальної мережі. Тепер настав час подумати про функціональність, яку ви хочете реалізувати у вашій соціальній мережі. Якщо ви дослідите користувачів Django, яких ви щойно створили, ви можете помітити, що вбудована модель користувача не має жодного функціоналу, який би дозволяв користувачам з'єднуватися. Щоб змоделювати зв'язки між користувачами, вам потрібно розширити стандартну модель користувача Django. Крок 2: Розширення моделікористувача Django На цьому етапі у вас є функціональний проект Django з кількома зареєстрованими користувачами. Наприкінці цього кроку у вас буде профіль для кожного користувача, пов'язаний з вбудованою моделлю користувача Django, що дозволить користувачам підключатися. Вам знадобиться спосіб зберігати інформацію про користувачів вашого додатку. Якби ви починали з нуля, вам би довелося створювати абсолютно нову модель користувача для цього. Замість цього, ви будете використовувати вбудовану модель користувача Django, покладаючись на добре протестовану реалізацію Django, щоб уникнути винайдення колеса автентифікації. Однак вам також знадобиться додаткова функціональність, яку не охоплює стандартна модель користувача: Як один користувач може стежити за іншим користувачем? Вам знадобиться спосіб пов'язувати користувачів з іншими користувачами. Хоча вбудована модель користувача в Django є корисною, її часто буває недостатньо при створенні користувацьких додатків, оскільки вона Примітка: У загальних термінах програмування ви побачите, що термін "розширити" коли фокусується на використовується, мінімальних йдеться про успадкування. Однак, налаштуваннях, необхідних для розширення моделі користувача у спільноті автентифікації. Чудовим способом Django може також стосуватися інших продовжувати використовувати вбудовані способів налаштування вбудованої можливості Django для керування користувачами, додаючи при цьому свої моделі користувача, які не специфічні налаштування, є розширення передбачають успадкування. моделі користувача. У цьому уроці ви зв'яжете дві окремі моделі за допомогою зв'язку "один до одного", що є одним з офіційно запропонованих способів вирішення цієї проблеми. Створіть модель профілю Ви розширите вбудовану модель користувача Django, використовуючи відносини один-на-один з невеликою і сфокусованою новою моделлю, Профілем. Ви створите цей профіль з нуля. Ця модель профілю буде відслідковувати додаткову інформацію, яку ви хочете зібрати про кожного користувача. Що вам потрібно на додаток до інформації про користувача, яку вже містить модель користувача Django? Візьміть свій блокнот і проведіть мозковий штурм щодо додаткових атрибутів користувача, які вам потрібні для вашої базової соціальної мережі, перш ніж розглядати можливі рішення: Рішення: Що вам потрібно? Показати/приховати Ви можете додати ще більше деталей про кожного користувача, ніж описано вище, наприклад, біографічну інформацію. Після того, як ви завершите цю серію уроків, додавання більшої кількості деталей до моделі профілю буде чудовою вправою. Модель профілю містить лише інформацію, яку створюють ваші користувачі, якщо вони вже мають обліковий запис користувача, що дозволяє вам дозволити Django обробляти процес реєстрації та автентифікації. Це один із запропонованих способів розширення існуючої моделі користувача, тому ви будете дотримуватися його. Ваша модель профілюповинна фіксувати зв'язки користувача з іншими профілями. Це і є це фундаментальна інформація, якої все ще бракує для успішного моделювання з'єднань між користувачами. Це означає, що ваша основна увага з моделлю профілю буде зосереджена на налаштувати його так, щоб він фіксував, хто стежить за профілем, і, навпаки, хто стежить за профілем. Вам потрібно створити лише одне поле для моделювання обох цих зв'язків. Це пов'язано з тим, що Django може розглядати профіль, який виконує наступні дії, як такий, що має зворотний зв'язок з профілем, за яким слідкують: ER-діаграма показує, що модель профілю з'єднується сама з собою за допомогою наступних зв'язків "багато до багатьох". Відкрийте файл models.py у вашому додатку dwitter і напишіть код для вашої Python нової моделі профілю: 1 # dwitter/models.py 2 3 з django.db імпорту моделей 5 4 from django.contrib.auth.models import User 6 class Profile(models.Model): 7 user = models.OneToOneField(User, on_delete=models.CASCADE) 8 follows = models.ManyToManyField( 9 "Я", Налаштувавши профіль таким чином, ви пов'язуєте кожен профіль точно з одним користувачем: 10 related_name="followed_by", 11 symmetrical=False, Рядок 4: Ви імпортуєте вбудовану модель користувача, яку хочете 12розширити. blank=True 13 ) Рядок 7: Ви визначаєте об'єкт типу OneToOneField під назвою user, який представляє зв'язок профілю з користувачем, створений за допомогою вбудованого додатку керування користувачами Django. Ви також визначаєте, що будь-який профіль буде видалено, якщо пов'язаного з ним користувача буде видалено. Рядки з 8 по 13: Ви визначаєте об'єкт ManyToManyField з наведеною нижче назвою поля, який може містити з'єднання з іншими профілями користувачів. Рядок 10: У цьому рядку ви передаєте значення ключового слова related_name у полі follows, що дозволяє вам отримати доступ до записів даних з іншого кінця цього зв'язку через описову назву "followed_by". Рядок 11: Ви також встановили symmetric у значення False, щоб ваші користувачі могли слідувати за кимось без того, щоб вони слідували за вами. Рядок 12: Нарешті, ви встановлюєте blank=True, що означає, що вашим користувачам не потрібно нікого відстежувати. Поле follows може залишатися порожнім. З налаштованим профілем ви можете запускати команди бази даних Django для поширення оновлень моделі до вашої бази даних: Оболонка (соціальний) $ python manage.py makemigrations Запуск команди makemigrations створює (соціальний) $ файл міграції, який реєструє зміни у вашій python manage.py базі даних, а команда migrate застосовує ці migrate зміни до бази даних. Тепер ви можете зареєструвати модель профілю в інтерфейсі адміністратора, щоб він відображав її на додаток до вбудованої моделі користувача: Python # dwitter/admin.py # ... з .models імпортувати Профіль # ... admin.site.register(Профіль) Після імпорту профілю з поточної програми та реєстрації його в інтерфейсі адміністратора, ви можете перезапустити сервер розробки: Оболонка (соціальний) $ python manage.py runserver Після запуску перейдіть до інтерфейсу адміністратора. Профілі відображаються під вашим Модель користувача в панелі DWITTER: Якщо ви натиснете на + Додати поруч з пунктом Профілі, Django покаже вам вікно створення профілю: Вам потрібно вибрати Користувача, який буде пов'язаний з профілем. Після того, як ви вибрали користувача зі спадного списку, ви можете натиснути на кнопку Зберегти, щоб створити свій перший профіль користувача. Після цього профіль з'явиться як об'єкт, який можна вибрати в розділі Фоловерів: Ви можете вибрати новий SAVE, щоб слідувати вашимоб'єкт профілю Об'єкт профілю (1) і знову натиснути на власний профіль користувача. Якщо ви вже Примітка: Переконайтеся, що ви створили інших користувачів на цьому створили профіль для всіх існуючих етапі, не забудьте створити профіль і для них. користувачів, перш ніж продовжити читання. В іншому випадку ви можете На цьому етапі ви вже маєте всю зіткнутися з помилками пізніше у цьому необхідну функціональність для посібнику. створення профілів і стеження за іншими профілями. Однак, відображення користувача і профілю в двох різних місцях, коли вони так тісно пов'язані між собою і є мінімально інформативними, може здатися незручним. За допомогою додаткових налаштувань інтерфейсу адміністратора ви можете покращити це налаштування. Видалити рекламу Відображення інформації про профіль на сторінціадміністратора користувача У цій серії уроків ви будете керувати створенням користувачів за допомогою адмінки. Кожному користувачеві потрібен обліковий запис і профіль, і ці два елементи мають бути пов'язані між собою. Замість того, щоб створювати користувача та його профіль у двох різних місцях, ви налаштуєте свій інтерфейс адміністратора, додавши вбудовану адмінку, яка дозволить вам редагувати і те, і інше в одній області. Поверніться до dwitter/admin.py, щоб Python # dwitter/admin.py # ... class ProfileInline(admin.StackedInline): model = Profile class UserAdmin(admin. ModelAdmin): model = User зареєструвати вашу нову модель профілю fields = ["ім'я користувача"] inlines = [ProfileInline] як вбудовану в стек замість стандартного admin.site.unregister(User) способу реєстрації моделі. Ви можете admin.site.register( використовувати клас UserAdmin, який ви User, UserAdmin) створили раніше, і налаштувати його, admin.site.unregist додавши er(Group) відповідну модель як # Видалити: admin.site.register(Profile) вбудовану: У цьому фрагменті коду ви створюєте стековану вбудовану лінію для Profile, створивши ProfileInline і успадкувавши її від admin.StackedInline. Після цього ви можете додати ProfileInline до складу вбудованих методів у UserAdmin. Примітка: inlines - це список, який може містити декілька записів, але в цьому Нарешті, виви також видалили рядок, де випадку хочете додатиостанній лише один. ви раніше реєстрували модель профілю окремо. Коли ви перейдете до інтерфейсу адміністратора, ви побачите, що запис "Профілі" зник з головної сторінки. Однак, коли ви перейдете до запису користувача на сторінці Користувачі, ви побачите інформацію про профіль поруч з інформацією про користувача: Інформація з профілю тепер відображається разом з інформацією з вбудованої моделі користувача Django, яку ви обмежили показом лише поля імені користувача. Це значне покращення, яке робить роботу з користувачами через інтерфейс адміністратора набагато зручнішою! Однак назви ваших профілів наразі важко інтерпретувати. Звідки ви знаєте, що об'єкт Python Profile (1) є профілем користувача admin? Без описової інформації, пов'язаної з вашою моделлю профілю, про це важко здогадатися. Щоб змінити це, поверніться до dwitter/models.py і додайте метод .__str__() до Profile: # dwitter/models.py class Profile(models.Model): user = models.OneToOneField(User, on_delete=models.CASCADE) follows = models.ManyToManyField( "self", related_name="followed_by", symmetrical=False, blank=True ) return defself.user.userna str (self): me Цим доповненням ви перевантажили стандартний метод .__str__() так, що він повертає значення імені користувача з асоційованого екземпляра моделі User. Перевірте результати в інтерфейсі адміністратора, перезавантаживши сторінку: Після цієї зміни об'єкт профілю, підключений до користувача admin, відображає ім'я цього користувача у списку підписників. Однак, жоден з додаткових користувачів, яких ви створили до цього часу, не має профілю. Згодом ви захочете, щоб кожен користувач мав профіль, який міститиме додаткову інформацію, пов'язану з цим користувачем. Вправа: Створення та асоціювання профілів Показати/приховати Оскільки ви хочете, щоб кожен користувач завжди мав один профіль, пов'язаний з ним, ви можете налаштувати Django для виконання цього завдання за вас. Кожного разу, коли ви створюєте нового користувача, Django має створювати також автоматично підбирати профіль користувача. Крім того, він має бути одразу пов'язаний з цим користувачем. Ви можете реалізувати це у models.py за допомогою сигналу. Видалити рекламу Крок 3: Реалізуйте хукпісля збереження Тепер у вас є користувачі і профілі, а також спосіб створювати і пов'язувати їх один з одним за допомогою інтерфейсу адміністратора. Наприкінці цього кроку ви зв'яжете їх так, щоб створення нового користувача автоматично створювало новий профіль і пов'язувало їх один з одним. На цьому кроці ви також попрактикуєтесь в інтерпретації повідомлень про помилки Django та пошуку шляхів дослідження і вирішення проблем за допомогою розробки на основі помилок. Координуйте користувачів і профілі за допомогою сигналу Ви розширили вбудовану модель Дослідити: Асоційовані користувачі та профілі вручну Показати/приховати користувача, але не створили автоматичний зв'язок між користувачами та профілями. Досі ви могли лише створювати користувачів і профілі та пов'язувати профіль з користувачем вручну через інтерфейс адміністратора. Було б непогано асоціювати новий Примітка: У документації Django згадується, що найкращим місцем для розміщення сигналів є новий підмодуль профіль з користувачем автоматично при signals.pyкористувача, вашого додатку. Однак, це створенні чи не так? Ви вимагає внесення змін у можете зробити це додаткових за допомогою конфігурацію вашого додатку. сигналів Django. Поверніться до Оскільки вашого вам потрібно створити лише один файлу dwitter/models.py. сигнал для цього підручника, ви Ви вже намітили, чого хочете досягти: збережете його в models.py. Коли ви створюєте нового користувача в базі даних, ви також хочете створити новий профіль і пов'язати його з цим користувачем. Ви можете реалізувати цю Python 1 # dwitter/models.py 2 3 from django.db.models.signals import post_save 4 5 # ... 6 7 def create_profile(sender, instance, created, **kwargs): функціональність за допомогою 8 якщо вона буде створена: post_save, який буде викликати об'єкт 9 user_profile = Profile(user=instance) 10 user_profile.save() функції create_profile щоразу, коли ваш код 11 виконує .save() користувацької моделі. 12# Створіть профіль для кожного нового користувача. Зверніть увагу, що create_profile() - це функція 13post_save.connect(create_profile, sender=User) верхнього рівня, яку ви визначаєте поза межами Profile: Ви додали додаткові рядки коду до файлу models.py: Третій рядок: Ви починаєте з імпорту post_save. Рядки з 7 по 10: Ви пишете нову функцію з назвою create_profile, яка використовує created, що post_save дозволяє вирішити, чи створювати новий екземпляр профілю. Ваш код буде продовжено, тільки якщо сигнал post-save вказує на те, що Django успішно створив об'єкт користувача. Рядок 9: Через те, що ви встановили зв'язок один-на-один між User і Profile, вам потрібно передати об'єкт User до конструктора Profile. Ви робите це, передавши екземпляр як аргумент до Profile. Рядок 10: Тут ви фіксуєте новий профіль у вашій базі даних за допомогою .save(). Рядок 13: Ви встановили сигнал після збереження для виконання create_profile() кожного разу, коли користувач модель виконує .save(). Ви робите це, передавши sender'у ключове слово User як аргумент. Ця реалізація сигналу після збереження створює новий профіль для кожного нового користувача. Ви автоматично пов'язуєте одного користувача з іншим, передаючи новоствореного користувача до конструктора профілю. Примітка: Коли спрацьовує сигнал після збереження, він повертає декілька змінних, тому ви перехоплення змінних, які вам зараз не потрібні, за допомогою **kwargs у визначенні функції create_profile(). На цьому можна було б закінчити, створивши блискуче чистий і порожній профіль для кожного нового користувача. Однак ви автоматично додасте власний профіль користувача до списку профілів, за якими він стежить, тож кожен користувач також бачитиме твіти, які він написав сам. Коли ви наважуєтеся вивчати щось нове, ви, швидше за все, натраплятимете на помилки направо і наліво. У наступному розділі ви попрактикуєтесь у спокої перед обличчям повідомлень про помилки і дізнаєтесь, як продовжувати рухатись у правильному напрямку, коли ви неминуче опинитесь у стані розриву зв'язку з Django. Додайте функціональності завдяки розробці на основі помилок Якщо ви використовуєте сигнал постзбереження саме так, як ви створили його в попередньому розділі, ви не побачите жодного з ваших твітів, коли перебуватимете на інформаційній панелі, яку ви налаштуєте пізніше. Але оскільки переглядати власні роздуми та дописи може бути цікаво, ви можете змінити свій код так, щоб за замовчуванням користувачі автоматично відстежували себе під час створення профілю. Часто буває важко написати правильний код з першого разу, коли ви намагаєтеся зробити щось своє, не дотримуючись покрокового підручника. У той же час, навчитися не зупинятися на досягнутому і знаходити дуже важливо! Тож ви попрактикуєтесь на помилках під час розробки цієї функції та дізнаєтесь, як вирішити ці проблеми. Примітка: Якщо ви вже звикли розробляти свій код, дотримуючись помилки або якщо ви вже працювали з сигналами Django раніше, то можете пропустити цей розділ і продовжити рефакторинг вашого коду для використання декоратора. Оскільки ви хочете відстежувати власний Python def create_profile(sender, instance, created, **kwargs): if created: профіль одразу після його створення, згадайте user_profile = про необов'язкове поле follow у профілі. Profile(user=instance, Можливо, ви можете додати екземпляр у follows=[instance]) user_profile.save() функцію хука після збереження за допомогою ключового слова follows, коли створюєте екземпляр профілю: Здається, це було швидко! Запустіть ваш сервер розробки і створіть нового користувача, щоб перевірити, чи все працює, як очікувалося. Ну, не зовсім. Ви побачите повідомлення про помилку: Python Traceback Пряме присвоювання передній частині множини багато-до-багатьох заборонено. Замість Django не знав, що цього робити з вашими використовуйте follows.set(). Python інструкціями, видав але спробував здогадатися вам підказку. follows=[екземпляр] замість з follows.set(), як і Видаліть профілю і нього спробуйте використати запропоновано у повідомленні про помилку: def create_profile(sender, instance, created, **kwargs): if created: user_profile = Profile(user=instanc user_profile.save() e) Змийте і повторіть ваш ручний тест, user_profile.follows.set (instance) створивши ще одного нового користувача в адмінці Django. Django все ще не зовсім задоволений вашим кодом, але він розуміє трохи більше, що означає, що він видасть вам інше повідомлення про помилку: Python Traceback ValueError в /admin/auth/user/add/ "<Profile: name>" повинен мати значення для поля "id", перш ніж можна буде використовувати цей Ви, мабуть, пам'ятаєте, що вам потрібно зв'язок "багато-до-багатьох". зафіксувати ваші об'єкти за допомогою .save(), перш ніж вони будуть записані у вашій базі даних. Коли Django створює запис у базі даних, він також автоматично створює поле id у цьому записі. У цьому повідомленні про помилку Django повідомляє вам, що екземпляр User Python def create_profile(sender, instance, created, **kwargs): if created: user_profile = Profile(user=instance) спочатку має існувати у вашій базі даних, user_profile.save() user_profile.follow щоб ви могли використати .set() для s.set(instance) додавання екземпляра до списку user_profile.save() слідування. Це корисна порада! Можливо, ви можете спочатку зберегти новий профіль у вашій базі даних, потім додати його до списку фоловерів і знову зберегти: Цього разу ви покладаєте великі надії на створення нового користувача! Однак Джанго знову заплутався: Python Traceback TypeError в об'єкті /admin/auth/user/a dd/ 'User' не є про помилку виглядає так, Повідомлення ітерабельним ніби Django намагається виконати ітерацію над екземпляром, який посилається на новостворений об'єкт User. Це те, що робить .set()? Настав час ознайомитися з документацією Django про зв'язки "багато-до-багатьох": Можна задаватинабори відношень: >>> Pythoa4.publications.all() n > <QuerySet >> [<Публікація: Наукові a4.publications.set([p новини>]>>. 3]) >>> >>> a4.publications.all() (Джерело) <QuerySet [<Публікація: Science Weekly>]>>. Схоже, що .set() дійсно вимагає Python def create_profile(sender, instance, created, **kwargs): if created: user_profile = ітеративного вводу, про що Django Profile(user=instan намагався повідомити вам у повідомленні ce) user_profile.save() про помилку. Отже, ви можете передати user_profile.follow список з екземпляром як єдиним елементом, s.set([екземпляр як і зазначено у документації Django: ]) user_profile.save() Ця зміна має дозволити .set() ітераційно переглядати переданий список і додавати профіль, пов'язаний з новим обліковим записом користувача, до списку облікових записів, за якими слідкує користувач. Схрестивши пальці, ви знову намагаєтеся створити нового користувача, але з'являється Python Traceback TypeError в /admin/auth/user/add/ TypeError: Поле 'id' очікувало число, а ще одна помилка: отримано <User: name>. Це чудово! Ваші повідомлення про помилки продовжують змінюватися, що дає вам додаткову інформацію. Ви на правильному шляху. Тепер Django повідомляє вам, що він отримав об'єкт User, але очікував на поле id. Ви налаштовуєте профілі так, щоб вони слідували за іншими профілями, але Django шукає лише .id об'єкта Profile. Після розширення моделі User ви можете отримати доступ до профілю користувача через його екземпляр користувача за допомогою .profile, а потім заглибитися в об'єкт, щоб отримати .id: Python def create_profile(sender, instance, created, **kwargs): if created: user_profile = Profile(user=instan Час для ще однієї спроби. Ви використовуєте інтерфейс адміністратора, щоб створити нового користувача, наприклад, ce) user_profile.save() Мартін, і тепер це працює: user_profile.follows.set([i nstance.profile.id]) user_profile.save() Вітаємо! Ви налаштували пост-збереження таким чином, що новостворений користувач автоматично переходить до свого профілю. Той самий хук пост-збереження також автоматично створив профіль. Створюючи цю функціональність, ви також Вправа: Альтернативне впровадження Показат практикувалися зберігати спокій перед и/приховати обличчям повторюваних повідомлень про помилки. Ви покращили своє розуміння того, як Django спілкується з вами, коли виникають непорозуміння. Рішення: Альтернативне впровадження Показат и/приховати Завдяки цій зміні ви вирішили проблему, яка полягала в тому, що ваші користувачі не бачили власних твітів на своїй інформаційній панелі. Тепер їхні твіти відображатимуться разом з твітами всіх інших користувачів, за якими вони стежать. На цьому етапі ви можете залишити цей код як є, але Django також надає більш елегантний спосіб реєстрації сигналів за допомогою декоратора. У наступному розділі ви переробите ваш хук постзбереження за допомогою receiver. Видалити рекламу Рефакторинг коду за допомогою декоратора Django постачається з декоратором Python приймачів, який дозволяє зробити написаний вами код більш лаконічним, не змінюючи його функціональності: 1 # dwitter/models.py 4 з приймача імпорту 2 django.dispatch 3 from django.db.models.signals import post_save 5 8 @receiver(post_sa 6 ve, # ... sender=User) 7 9 def create_profile(sender, instance, created, **kwargs): 10 якщо вона буде створена: 11 user_profile = Profile(user=instance) 12 user_profile.save() 13 user_profile.follows.add(екземпляр.профілю) 16 # Видалити: 14 post_save.connect(create_profi user_profile.save() 15 le, sender=User) За допомогою цього рефакторингу ви застосували три зміни до своєї кодової бази: 1. для отримувача з django.dispatch. Рядок 4: Ви додаєте імпорт 2. Р ядок 8: Ви застосовуєте декоратор до create_profile, передаючи йому post_save і передаючи модель User відправнику. Передаючи модель, ви пов'язуєте post_save з подіями, пов'язаними з моделлю User, так само, як ви робили це раніше з .connect(). 3. Р ядок 16: Ви видаляєте рядок коду, який раніше пов'язував post_save з User як відправником, оскільки ви вже створили цей зв'язок за допомогою аргументів, наданих декоратору у рядку 8. Пам'ятайте, що вам потрібно спочатку зберегти новостворений об'єкт Profile, щоб він існував. Лише після цього ви можете додати новостворений .profile користувача до вашого нового user_profile. Нарешті, вам потрібно зберегти зміни вдруге, щоб поширити оновлену асоціацію у вашій базі даних. Примітка: Якщо вас здивувало використання .add() у наведеному вище фрагменті коду, то візьміть ще раз подивіться на розбірний розділ під назвою "Альтернативне впровадження" в попередньому розділі. Вітаємо, ви успішно налаштували більшу частину бек-енду вашої соціальної мережі Django. Ви реалізували модель взаємовідносин між вашими користувачами та Django профілі в соціальних мережах! Кожного разу, коли ви створюєте нового користувача, він також отримує профіль користувача і одразу ж переходить до свого профілю. Крім того, профілі користувачів можуть слідувати один за одним. Але чи працює це? Підтвердьте автоматичну асоціацію в адмінці Поверніться до інтерфейсу адміністратора і створіть нового користувача за допомогою наданої форми. Все, що вам потрібно зробити, це вказати ім'я користувача і натиснути на кнопку "Зберегти". Наприклад, ви можете додати ще одного користувача на ім'я rainn: Коли ви перевірите сторінку зміни користувача, ви побачите, що Django автоматично створив профіль для нового користувача і додав цей профіль до списку профілів, за якими він стежить: Ви можете побачити, що користувач стежить за власним профілем, тому що його ім'я профілю в списку підписників має сірий фон. Тепер ви можете створювати нових користувачів за допомогою інтерфейсу адміністратора Django, і вони автоматично отримають відповідний профіль. Django також налаштує їхній профіль на стежити за собою, що дозволить відображати власні твіти поруч з твітами інших людей на своїй інформаційній панелі. Ви можете змінити профілі, на які користувач підписується, вибравши або знявши позначку з назв профілів у списку "Підписники" і натиснувши кнопку "Зберегти". Щоб вибрати кілька профілів або скасувати вибір певного профілю, вам потрібно натиснути ⌃ Ctrl у Примітка: Ви можете налаштувати зовнішню автентифікацію через вбудовану систему керування користувачами Django пізніше, і вам не Windows і Linux або ⌘ Cmd у macOS, потрібно буде вноситиCtrl, жодних змін до утримуючи клавішу і натиснути на назву профілю. бекенду, щоб функціонал продовжував працювати належним Але поки що тут не на що дивитися. Досі чином. ви лише ховалися в адмінці Django. Можливо, починаєте втомлюватися Коли хтосьви створює новий обліковий запис, від готових сторінок, які надає Django, і вам він отримує особистий профіль і, крім того, кортить написати кілька шаблонів Django, отримує свій перший самостійний щоб побачити, як можна відобразити ці фоловінг безкоштовно! зв'язки моделі у користувацькому інтерфейсі вашого додатку. Саме над цим ви будете працювати у другій частині цієї серії уроків! Ви почнете створювати інтерфейс вашого веб-додатку і дізнаєтеся, як зробити його гарним за допомогою CSS-фреймворку Bulma. Висновок Вітаємо вас! На цьому етапі ви завершили першу частину цієї серії підручників зі створення базової соціальної мережі за допомогою Django. У першій частині цієї серії уроків ви дізналися, як цезробити: Реалізація зв'язків "один-до-одного" та "багато-до-багатьох" між моделями Django Розширте модель користувача Django за допомогою користувацької моделі профілю Налаштуйте інтерфейс адміністратора Django Ви також отримали додаткову практику у створенні проекту Django та виконанні пов'язаних з цим завдань. Ви попрактикувалися в читанні повідомлень про помилки Django та пошуку рішень на основі інформації, яку вони надають. Ви можете завантажити код першої Отримати вихідний код: Натисніть частини цього проекту, натиснувши тут, щоб отримати вихідний код, на посилання нижче і використати перейшовши до папки який ви можете для source_code_final/: створення соціальної мережі за допомогою Django. Видалити рекламу Наступні кроки для вашої базової соціальної мережі за допомогою Django Тепер, коли ви прочитали першу частину цієї серії, ви можете перейти до другої частини, в якій ви створите інтерфейс Django у стилі Bulma. У другій частині підручника ви створите інтерфейсні сторінки для ваших профілів користувачів і зробите їх гарними. Під час подальшої роботи над проектом ви Частина 1 Част можете повертатися до цієї частини ина 2 " підручника, звірятися з планом, який ви склали в загальному огляді проекту, і оновлювати свій план у процесі роботи. Позначит и як виконано � Трюки на Python � Отримайте короткий та милий трюк Python, доставлений заадресою вашу поштову скриньку кожні два дні. Ніякого спаму. Відпишіться будьколи. Куратор команда Real Python. Адреса електронної пошти Надішліть мені трюки на Python " Про Мартіна Бройса Мартін любить автоматизацію, безглузді жарти та змій, і все це вписується у спільноту Python. Йому подобається вчитися та досліджувати, і він також готовий поговорити про це. Він пише та записує контент для Real Python та CodingNomads. " Більше про Мартіна Кожен підручник на Real Python створюється командою розробників, щоб він відповідав нашим високим стандартам якості. Ось члени команди, які працювали над цим підручником: Олдрен Бартош Девід Гейр Арне Кейт Філіп Сейді. Опануйте реальні навички Python з необмеженим доступом до реального Python Приєднуйтесь до нас і отримайте доступ до тисяч підручників, Що ти думаєш? практичних Оцініть цю статтю: відеокурсів та Tweet Поділитися Поділитися Email спільноти експертів Python: Що ви взяли для себезна пам'ять або що вам найбільше сподобалося? Як ви Підвищуйте свої роботи з навички збираєтесь навички застосувати набуті Python " на практиці? Залиште коментар нижче і дайте нам знати. Поради щодо коментування: Найкорисніші коментарі - це ті, що написані з метою навчитися або допомогти іншим студентам. Отримайте поради, як ставити правильні запитання та відповіді на поширені запитання на нашому порталі підтримки. Хочете поспілкуватися в реальному часі? Відвідайте реальний чат спільноти Python або приєднуйтесь до наступної сесії запитань та відповідей "Робочі години" в прямому ефірі. Щасливого Pythoning! Продовжуйте вчитися Пов'язані категорії уроків: проміжна веб-розробкаdjango Видалити рекламу © 2012-2023 Real Python ⋅ Інформаційний бюлетень ⋅ Подкаст ⋅ YouTube ⋅ Twitter ⋅ Facebook ⋅ Instagram ⋅ Навчальні посібники з Python ⋅ Пошук ⋅ Політика конфіденційності ⋅ Енергетична політика ⋅ Реклама ⋅ Контакти ❤ Щасливого пітонінгу!