diff --git a/.github/list_languages b/.github/list_languages new file mode 100755 index 00000000000..27ee2e7999e --- /dev/null +++ b/.github/list_languages @@ -0,0 +1,35 @@ +#!/usr/bin/env python3 + +import argparse +import json +import os +from pathlib import Path + + +def parse_langs(langs, include_beta): + for line in langs.readlines(): + description = line[3:-7] + code = line[-5:-3] + + if include_beta or 'beta' not in description: + yield code, description + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument('--include-beta', help='Include beta languages', default='false', + choices=('true', 'false')) + parser.add_argument('--langs-file', help='LANGS.md to use', + type=argparse.FileType('r', encoding='UTF-8'), + default=(Path(__file__).absolute().parent.parent / 'LANGS.md').as_posix()) + args = parser.parse_args() + + languages = dict(parse_langs(args.langs_file, args.include_beta == 'true')) + + if 'GITHUB_ACTION' in os.environ: + print(f'::set-output name=languages::{json.dumps(list(languages.keys()))}') + for code, language in languages.items(): + print(f'{language} ({code})') + + +if __name__ == '__main__': + main() diff --git a/.github/workflows/translations.yml b/.github/workflows/translations.yml new file mode 100644 index 00000000000..434e1f1aa4e --- /dev/null +++ b/.github/workflows/translations.yml @@ -0,0 +1,54 @@ +name: Update translations + +on: + workflow_dispatch: + inputs: + include_beta: + type: boolean + default: false + description: Include beta languages + +env: + GIT_AUTHOR_NAME: Django Girls Automation + GIT_AUTHOR_EMAIL: automation@djangogirls.org + +jobs: + list_languages: + name: List languages + runs-on: ubuntu-latest + outputs: + languages: ${{ steps.set_list.outputs.languages }} + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Set the language list + id: set_list + run: ./.github/list_languages --include-beta ${{ inputs.include_beta }} + + update_language: + name: 'Update ${{ matrix.language }} translations from Crowdin' + needs: list_languages + if: ${{ needs.list_languages.outputs.languages != '[]' }} + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + language: ${{ fromJson(needs.list_languages.outputs.languages) }} + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Update language + run: | + wget https://crowdin.com/backend/download/project/django-girls-tutorial/${{ matrix.language }}.zip + unzip ${{ matrix.language }}.zip + find ${{ matrix.language }} -name '*.md' -delete + rsync -av master/${{ matrix.language }}*/* ${{ matrix.language }}/ + rm -rf ${{ matrix.language }}.zip master + - name: Open a PR + uses: peter-evans/create-pull-request@v3 + with: + commit-message: "Update ${{ matrix.language }} translations from Crowdin" + branch: "update_translations/${{ matrix.language }}" + title: "Update ${{ matrix.language }} translations from Crowdin" + body: '' + delete-branch: true diff --git a/uk/GLOSSARY.md b/uk/GLOSSARY.md index 21fed491ffc..a5c11c32bd2 100644 --- a/uk/GLOSSARY.md +++ b/uk/GLOSSARY.md @@ -1,2 +1,3 @@ # Редактор коду -Редактор коду - це програма, що дозволяє зберегти ваш код, так що можна повернутися до його редагування пізніше. Ви можете дізнатися, звідки його взяти з розділу [про текстовий редактор](./code_editor/README.md) + +Редактор коду - це додаток, що дозволяє зберегти ваш код, так що можна повернутися до його редагування пізніше. Ви можете дізнатися, де його знайти у розділі [Редактор коду](./code_editor/README.md) \ No newline at end of file diff --git a/uk/README.md b/uk/README.md index 39af52cf8d7..806676d959c 100644 --- a/uk/README.md +++ b/uk/README.md @@ -1,45 +1,51 @@ -# Навчальний посібник Django Girls -[![Gitter](https://badges.gitter.im/Join Chat.svg)](https://gitter.im/DjangoGirls/tutorial?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) +# Посібник Django Girls -> Ця робота ліцензована міжнародною ліцензією Creative Commons Attribution-ShareAlike 4.0 -International License. Щоб переглянути копію цієї ліцензії, відвідайте -https://creativecommons.org/licenses/by-sa/4.0/ +[![Gitter](https://badges.gitter.im/DjangoGirls/tutorial.svg)](https://gitter.im/DjangoGirls/tutorial) -## Translation +> Ця робота ліцензована міжнародною ліцензією Creative Commons Attribution-ShareAlike 4.0. Щоб переглянути копію цієї ліцензії, відвідайте https://creativecommons.org/licenses/by-sa/4.0/ -This tutorial has been translated from English by a group of awesome volunteers: [chupakabra](https://github.com/chupakabra), [Oleksandr Redko](https://github.com/alexandear), [Taras Bunyk](https://github.com/bunyk), [msihor](https://crowdin.com/profile/msihor), [Olesia Hrydzhuk](https://github.com/Zlira), [Andriy Kohut](https://github.com/andriykohut), [Artem Suchov](https://crowdin.com/profile/suchov), [Artem Godlevskyi](https://github.com/errno), [Alex Vykalyuk](https://crowdin.com/profile/alekzvik), [Kostyantyn Leschenko](https://crowdin.com/profile/kleschenko). Special thanks for all the free time they sacrificed to make that happen! <3 +## Вітаємо +Вітаємо у посібнику Django Girls! Ми раді вас тут бачити. :)  В цьому курсі ви побачите із середини, як працюють вебтехнології. Ми пропонуємо вам огляд усіх шматочків, які мають об'єднатись разом, щоб зробити мережу такою, як ми її знаємо. + +Як і з усім невідомим, це буде пригодою - але не хвилюйтесь, бо якщо у вас вистачило сміливості бути тут, ви впораєтесь. :) ## Вступ -Чи ви коли-небудь відчували, що світ крутиться все більше і більше навколо технологій, а ви в певній мірі пасете задніх? Чи вас колись цікавило, як створити веб-сайт, однак, ніколи не вистачало достатньої мотивації, щоб почати? Чи ви колись вважали, що світ програмування є занадто складним для вас, щоб навіть пробувати робити щось самостійно? +Чи ви колись відчували, що світ крутиться все більше і більше навколо технологій, про які ви (поки) нічого не знаєте? Чи вас колись цікавило, як створити вебсайт, але ніколи не вистачало достатньої мотивації, щоб почати? Чи ви колись вважали, що світ програмування є занадто складним для вас, щоб навіть пробувати робити щось самостійно? -Що ж, маємо гарні новини для вас! Програмування - це не так складно, як може здатися, і ми хочемо вам показати, наскільки веселим цей процес може бути. +Що ж, маємо гарні новини для вас! Програмування - це не так складно, як може здаватися, і ми хочемо вам показати, наскільки веселим може бути цей процес. -Даний навчальний посібник не перетворить вас магічним чином на програміста. Якщо ви хочете розбиратися у цьому, то вам потрібні будуть для цього місяці або навіть роки теорії та практики. Однак ми хочемо показати вам, що програмування або створення веб сайтів не є настільки складним, як це здається. Спробуємо пояснити різні поняття настільки, наскільки зуміємо, то ж ви не будете почуватися заляканими технологіями. +Даний навчальний посібник не перетворить вас магічним чином на програмістку. Якщо ви хочете розбиратися у цьому, то вам потрібні місяці або навіть роки навчання та практики. Але, наша мета показати вам, що програмування або створення вебсайтів не таке складне, як здається. Ми будемо намагатись так добре пояснити різні уривки та частини, як тільки зможемо, тож технології вас не лякатимуть. -Сподіваємось, ми зможемо навчити вас полюбити технології настільки, наскільки любимо їх ми самі! +Сподіваємось, що нам вдасться зробити так, щоб ви любили технологію як любимо її ми! ## Що ви вивчите під час освоєння посібника? -По завершенню даного посібника, ви будете мати простий робочий веб-додаток - свій власний блог. Ми покажемо вам як опублікувати його в Інтернеті, тож інші також зможуть оцінити вашу роботу! +По завершенню даного посібника, ви будете мати простий, робочий вебдодаток: свій власний блог. Ми покажемо вам, як опублікувати його в інтернеті, тож інші також зможуть оцінити вашу роботу! -Це буде (в більшій чи меншій мірі) виглядати наступним чином: +Це буде (більшою чи меншою мірою) виглядати таким чином: -![Рисунок 0.1](images/application.png) +![Figure 0.1](images/application.png) -> Якщо ви працюєте над матеріалами самостійно і не маєте інструктора, що зміг би допомогти у разі певної проблеми, для вас існує чат: [![Gitter](https://badges.gitter.im/Join Chat.svg)](https://gitter.im/DjangoGirls/tutorial?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge). Ми попросили наших інструкторів і попередніх учасників бути там час від часу та допомагати іншим із освоєнням матеріалу! Не бійтеся задавати свої питання! +> Якщо ви працюєте над матеріалами самостійно і не маєте інструктора, що зміг би допомогти у разі певної проблеми, ми маємо для вас чат: [![Gitter](https://badges.gitter.im/DjangoGirls/tutorial.svg)](https://gitter.im/DjangoGirls/tutorial). Ми попросили наших інструкторів і попередніх учасників бути там час від часу і допомагати іншим із освоєнням матеріалу! Не бійтеся задавати свої питання! Гаразд, [почнемо з самого початку...](./how_the_internet_works/README.md) -## Коротка інформація та вклад +## Робота з посібником вдома + +Це чудово - брати участь в Django Girls workshop, але ми розуміємо, що не завжди є можливість його відвідати. Тому ми за те, щоб ви намагались проходити цей посібник вдома. Для тих, хто навчається вдома, ми зараз готуємо відео, які можуть спростити використання посібника самостійно. Вони досі знаходяться в розробці, але з часом все більше цікавих речей можна буде знайти на каналі [Coding is for girls](https://www.youtube.com/channel/UC0hNd2uW8jTR5K3KBzRuG2A/feed) в YouTube. + +У кожному розділі, що вже готовий, є посилання на відповідне відео. + +## Про проєкт та як долучитись -Цей посібник підтримується спільнотою [DjangoGirls](https://djangogirls.org/). Якщо ви знайдете якісь помилки або захочете зробити певні оновлення, будь ласка, [виконуйте вказівки з частини про вклад](https://github.com/DjangoGirls/tutorial/blob/master/README.md). +Цей посібник підтримується спільнотою [DjangoGirls](https://djangogirls.org/). Якщо ви знайдете якісь помилки або захочете зробити певні оновлення, будь ласка, [виконуйте вказівки, як долучитись до проєкту](https://github.com/DjangoGirls/tutorial/blob/master/README.md). ## Чи не бажаєте допомогти нам із перекладом посібника на інші мови? -На даний момент, переклади підтримуються на платформі crowdin.com: +На цей момент переклади підтримуються на платформі crowdin.com : https://crowdin.com/project/django-girls-tutorial -Якщо ваша мова не перерахована на crowdin, будь ласка, [відкрийте нову тему](https://github.com/DjangoGirls/tutorial/issues/new), що інформує про мову, таким чином ми зможемо додати її. +Якщо ваша мова не перерахована на [crowdin](https://crowdin.com/), будь ласка, відкрийте нову тему, що інформує про мову, таким чином ми зможемо додати її.

\ No newline at end of file diff --git a/uk/SUMMARY.md b/uk/SUMMARY.md index ea34bf8e38d..a333ad851f4 100644 --- a/uk/SUMMARY.md +++ b/uk/SUMMARY.md @@ -1,7 +1,16 @@ # Зміст * [Вступ](README.md) -* [Встановлення](installation/README.md) +* [Встановлення](installation/README.md) + * [Командний рядок](installation/README.md#command-line) + * [Python](installation/README.md#python) + * [Редактор Коду](installation/README.md#code-editor) + * [Віртуальне середовище](installation/README.md#virtualenv) + * [Django](installation/README.md#django) + * [Git](installation/README.md#git) + * [GitHub](installation/README.md#github-account) + * [PythonAnywhere](installation/README.md#pythonanywhere-account) +* [Встановлення (chromebook)](chromebook_setup/README.md) * [Як працює Інтернет](how_the_internet_works/README.md) * [Вступ до командного рядку](intro_to_command_line/README.md) * [Встановлення Python](python_installation/README.md) @@ -13,14 +22,14 @@ * [Django моделі](django_models/README.md) * [Django адміністратор](django_admin/README.md) * [Розгортання!](deploy/README.md) -* [Django urls](django_urls/README.md) +* [Django URL-адреси](django_urls/README.md) * [Django відображення - час творити!](django_views/README.md) * [Вступ до HTML](html/README.md) * [Django ORM (Querysets)](django_orm/README.md) * [Динамічні дані в шаблонах](dynamic_data_in_templates/README.md) * [Django шаблони](django_templates/README.md) * [CSS - зроби це красиво](css/README.md) -* [Шаблонне розширення](template_extending/README.md) +* [Розширення шаблону](template_extending/README.md) * [Розширте свою програму](extend_your_application/README.md) * [Django форми](django_forms/README.md) -* [Що далі?](whats_next/README.md) +* [Що далі?](whats_next/README.md) \ No newline at end of file diff --git a/uk/chromebook_setup/README.md b/uk/chromebook_setup/README.md new file mode 100644 index 00000000000..5e76e25429c --- /dev/null +++ b/uk/chromebook_setup/README.md @@ -0,0 +1,5 @@ +# Налаштування на Chromebook + +> **Примітка** Якщо ви вже виконали [кроки встановлення](../installation/README.md), не потрібно робити це знову – ви можете перейти безпосередньо до [Вступ до Python](../python_introduction/README.md). + +{% include "/chromebook_setup/instructions.md" %} \ No newline at end of file diff --git a/uk/chromebook_setup/instructions.md b/uk/chromebook_setup/instructions.md new file mode 100644 index 00000000000..6c295bffbff --- /dev/null +++ b/uk/chromebook_setup/instructions.md @@ -0,0 +1,158 @@ +Ви можете [перейти у цей розділ](http://tutorial.djangogirls.org/en/installation/#install-python), якщо ви не використовуєте Chromebook. Якщо ви використовуєте Chromebook, процес встановлення може відрізнятись. Ви можете ігнорувати інші інструкції з установки. + +### Cloud IDE (PaizaCloud Cloud IDE, AWS Cloud9, Glitch.com) + +Cloud IDE це інструмент який надає вам редактор коду та доступ до комп'ютера в мережі Інтернет де ви можете встановлювати, писати та запускати програми. Протягом курсу, сloud IDE буде виконувати функцію вашого *локального ком'ютера*. Ви будете запускати команди в терміналі як і ваші одногрупники на OS X, Ubuntu або Windows, але ваш термінал буде керувати комп'ютером виділеним для вас Cloud IDE. Тут ви знайдете інструкції для Cloud IDEs (PaizaCloud Cloud IDE, AWS Cloud9, Glitch.com). Ви можете обрати одне з cloud IDE і використовувати інструкції для нього. + +#### PaizaCloud Cloud ID + +1. Перейдіть на [PaizaCloud Cloud IDE](https://paiza.cloud/) +2. Зареєструйте обліковий запис +3. Клацніть«*New Server*» і оберіть «Django app» +4. Натисніть на кнопку Terminal (в лівій частині вікна) + +Тепер ви маєте побачити інтерфейс з боковою панеллю так кнопками зліва. Натисніть кнопку Terminal щоб відкрити вікно терміналу з наступним виводом: + +{% filename %}Terminal{% endfilename %} + + $ + + +Термінал на PaizaCloud IDE готовий до ваших інструкцій. Ви можете змінити розмір або максимізувати це вікно, щоб зробити його трохи більшим. + +#### AWS Cloud9 + +В даний час Cloud 9 вимагає зареєструватися за допомогою AWS і ввести інформацію кредитної карти. + +1. Встановити Cloud 9 з [веб-магазину Chrome](https://chrome.google.com/webstore/detail/cloud9/nbdmccoknlfggadpfkmcpnamfnbkmkcp) +2. Перейдіть до [c9.io](https://c9.io) та натисніть *Get started with AWS Cloud9* +3. Створіть обліковий запис AWS (потрібна інформація про кредитну картку, але ви можете користуватись цим безкоштовно) +4. В AWS-Dashboard, введіть *Cloud9* в рядку пошуку і клацніть на ньому +5. У панелі Cloud9 натисніть *Create environment* +6. Назвіть його *django-girls* +7. Під час налаштування параметрів виберіть *Create a new instance for environment (EC2)* для "Environment Type" та *t2.micro* для "Instance type" (він має сказати "Free-tier eligible."). Економне налаштування за замовчуванням задовільне, а ви можете залишити інші значення також без змін. +8. Натисніть *Next step* +9. Натисніть *Create environment* + +Тепер ви повинні побачити інтерфейс із бічною панеллю, великим основним вікном з деяким текстом, і маленьке вікно внизу, що виглядає приблизно так: + +{% filename %}bash{% endfilename %} + + yourusername:~/workspace $ + + +Ця нижня область є вашим терміналом. Ви можете використовувати термінал, щоб відправляти інструкції на віддалений комп'ютер Cloud9. Ви можете змінити розмір вікна, щоб зробити його трохи більшим. + +#### Glitch.com хмара IDE + +1. Перейдіть на Glitch.com +2. Зареєструйтесь за обліковим записом ( https://glitch.com/signup) або використовуйте акаунт GitHub, якщо маєте. (Дивіться інструкцію до GitHub нижче) +3. Натисніть Новий проект та оберіть Головна сторінка +4. Натисніть на випадаючому списку інструментів (внизу лівої сторони вікна) , потім натисніть на конпку терміналу , щоб відкрити закладку командного рядка таким чином: + +{% filename %} Термінал {% endfilename %} + + Програма@ ім'я твого проекту + + +Тобі не потрібно створювати віртуальне середовище при використанні Glitch.com як Ваш Cloud.IDE + +{% filename %}glitch.json{% endfilename %} + +```json +{ + "install": "pip3 install -r requirements.txt --user", + "start": "bash start.sh", + "watch": { + "throttle": 1000 + } +} +``` + +{% filename %}requirements.txt{% endfilename %} + + Django~={{ book.django_version }} + + +{% filename %}.bash_profile{% endfilename %} + +```bash +alias python=python3 +alias pip=pip3 +``` + +{% filename %}start.sh{% endfilename %} + +```bash +chmod 600 .bash_profile +pip3 install -r requirements.txt --user +python3 manage.py makemigrations +python3 manage.py migrate +python3 manage.py runserver $PORT +``` + +Once these files are created, go to the Terminal and execute the following commands to create your first Django project: + +{% filename %}Terminal{% endfilename %} + + django-admin.py startproject mysite . + refresh + + +In order to see detailed error messages, you can activate Django debug logs for your Glitch application. Simply add the following at the end of the `mysite/settings.py` file. + +{% filename %}mysite/settings.py{% endfilename %} + +```python +LOGGING = { + 'version': 1, + 'disable_existing_loggers': False, + 'handlers': { + 'file': { + 'level': 'DEBUG', + 'class': 'logging.FileHandler', + 'filename': 'debug.log', + }, + }, + 'loggers': { + 'django': { + 'handlers': ['file'], + 'level': 'DEBUG', + 'propagate': True, + }, + }, +} +``` + +This will create a `debug.log` file detailing Django operations and any error messages that might come up, making it much easier to fix if your website does not work. + +The initial restarting of the Glitch project should fail. (If you click on the top dropdown button `Show` then click on `In a New Window`, you will receive a `DisallowedHost` error message.) Do not worry about it at this stage, the tutorial will fix this as soon as you update the Django settings of your project in the `mysite/settings.py` file. + +### Віртуальне середовище + +Віртуальне середовище (також зване virtualenv) - це як приватна скриня, яку ми можемо наповнювати корисним комп'ютерним кодом для проекту, над яким ми працюємо. Ми використовуємо їх для зберігання різноманітних частин коду, які потрібні нам для різних проєктів як окремі частини, так щоб не було плутанини між проєктами. + +Запуск: + +{% filename %}Cloud 9{% endfilename %} + + mkdir djangogirls + cd djangogirls + python3 -m venv myvenv + source myvenv/bin/activate + pip install django~={{ book.django_version }} + + +(зверніть увагу на те що в останньому рядку ми використовуємо знак тильди слідом за яким йде знак рівності:`~=`). + +### GitHub + +Створіть [GitHub](https://github.com) обліковий запис. + +### PythonAnywhere + +Посібник Django Girls містить розділ по так званому Розгортанні, що є процесом отримання коду, який забезпечує роботу вашого нового веб-додатка і переміщення його на загальнодоступний комп’ютер (так званий сервер), отож люди можуть бачити вашу роботу. + +Ця частна є трохи дивною в навчанні по Chromebook, оскільки ми вже використовуємо комп'ютер, який знаходиться в Інтернеті (на відміну від, скажімо, ноутбука). Однак, це все ще корисно, оскільки ми можемо розглядати нашу робочий простір Cloud 9 як місце для нашої роботи "в процесі" і Python Anywhere як місце, де можна показати наші речі,коли вони стають більш завершеними. + +Таким чином, зареєструйте новий обліковий запис Python Anywhere на [www.pythonanywhere.com](https://www.pythonanywhere.com). \ No newline at end of file diff --git a/uk/code_editor/README.md b/uk/code_editor/README.md index da85dfaae1c..38b3040be03 100644 --- a/uk/code_editor/README.md +++ b/uk/code_editor/README.md @@ -1,7 +1,11 @@ # Редактор коду -Наближаємось до написання нашого першого рядка коду, отже, настав час завантажити редактор коду! +> Для читачів вдома: відеоверсія цього розділу (разом із попереднім) - [Встановлення Python та редактора коду](https://www.youtube.com/watch?v=pVTaqzKZCdA&t=4m43s) (англ.). -> **Примітка** Ви могли зробити це раніше у розділі "Встановлення" - якщо вже завантажили редактор, то можете відразу перейти до наступного розділу! +Наближаємось до написання нашого першого рядка коду, отже настав час завантажити редактор коду! -{% include "/code_editor/instructions.md" %} +> **Примітка:** Якщо ви використовуєте хромбук, пропустіть цей розділ і переконайтеся, що ви слідуєте інструкції [ Встановлення (хромбук)](../chromebook_setup/README.md). Вибраний вами хмарний IDE (PaizaCloud Cloud IDE або AWS Cloud9) включає в себе редактор коду, і коли ви відкриваєте файл в IDE з меню Файл, ви автоматично запускаєте редактор. +> +> **Примітка:** Ви могли вже зробити це у розділі "Встановлення" – якщо так, можете одразу перейти до наступного розділу! + +{% include "/code_editor/instructions.md" %} \ No newline at end of file diff --git a/uk/code_editor/instructions.md b/uk/code_editor/instructions.md index b877de82df1..d6b73af8686 100644 --- a/uk/code_editor/instructions.md +++ b/uk/code_editor/instructions.md @@ -1,34 +1,37 @@ -Існує багато різноманітних редакторів і здебільшого все зводиться до персональних вподобань. Більшість Python програмістів використовують складні, але надзвичайно потужні IDE (англ. Integrated Development Environments - інтегровані середовища розробки), такі як PyCharm. Однак, вони менш доцільні для початківців; ми пропонуємо такі ж потужні, але більш простіші інструменти. +Серед великого різноманіття редакторів вибір залежить від особистих вподобань. Більшість програмістів Python користуються комплексними і дуже потужними IDE (англ. Integrated Development Environments - Інтегровані середовища розробки), наприклад, PyCharm. Хоча новачкам, мабуть, вони не дуже підходять; ми рекомендуємо такі ж потужні, але значно простіші. -Нижче наведено перелік наших вподобань, але ви також можете попросити поради в своїх тренерів - тоді буде простіше отримувати від них допомогу. +Нижче наведено наші пропозиції, але не соромтесь запитати вашого наставника якими є його вподобання - простіше буде отримувати допомогу від нього. -## Gedit +## Visual Studio Code -Gedit є відкритим, безкоштовним редактором, доступним для усіх операційних систем. +Visual Studio Code - це редактор для написання коду, який розробив Microsoft для Windows, Linux та macOS. Він включає підтримку налагодження, вбудоване керування Git, підсвітку синтаксису, інтелектуальне завершення коду, сніппети та рефакторинг коду. -[Завантажте його можна тут](https://wiki.gnome.org/Apps/Gedit#Download) +[Завантаження тут](https://code.visualstudio.com/) -## Sublime Text +## Gedit -Sublime Text є дуже популярним редактором із безкоштовним пробним періодом. Він легко встановлюється та простий у використанні, а також доступний для усіх операційних систем. +Gedit - це безкоштовний редактор з відкритим кодом, що доступний для всіх операційних систем. -[Завантажити його можна тут](https://www.sublimetext.com/) +[Завантаження тут](https://wiki.gnome.org/Apps/Gedit#Download) -## Atom +## Sublime Text -Atom - це найновіший редактор коду, створений [GitHub](https://github.com/). Він є безкоштовним, відкритим, легко встановлюється та простий у користуванні. Доступний для Windows, OSX і Linux. +Sublime Text - це дуже популярний редактор із безкоштовним періодом оцінювання та є доступним для всіх операційних систем. -[Завантажити його можна тут](https://atom.io/) +[Завантаження тут](https://www.sublimetext.com/) +## Atom +Atom - ще один поширений редактор. Він безкоштовний, має відкритий вихідний код та доступний для Windows, OS X та Linux. Atom розробили в [GitHub](https://github.com/). -## Чому ми встановлюємо редактор коду? +[Завантаження тут](https://atom.io/) -Ви напевне запитуєте себе, чому ми встановлюємо спеціальний редактор для коду, а не використовуємо щось на зразок Word чи Notepad. +## Яка причина встановлення редактора коду? -По-перше, код повинен зберігатись як **звичайний текст**, а проблемою таких програм як Word чи Textedit є те, що вони не створюють звичайний текст, вони продукують так званий "збагачений" текст (зі шрифтами та форматуванням), використовуючи спеціальні формати, такі як [RTF (Rich Text Format)](https://en.wikipedia.org/wiki/Rich_Text_Format). +Ви, мабуть, дивуєтесь чому ми інсталюємо особливе ПЗ редактора коду, замість того щоб використовувати щось на зразок Word або Notepad. -Другою причиною є те, що редактори коду спеціалізуються саме на редагуванні коду, тому вони можуть запропонувати корисні функції на зразок підсвітки коду залежно від його значення чи автоматичного закривання дужок. +По-перше, код має бути **простим текстом**, а проблема програм як Word або Textedit в тому, що вони загалом не створюють простий текст, вони створюють форматований текст (що має шрифти та форматування), використовуючи нестандартні формати на зразок [RTF (Rich Text Format)](https://en.wikipedia.org/wiki/Rich_Text_Format). -Ми побачимо все це в дії пізніше. Скоро ви вважатимете свого вірного редактора коду одним із найулюбленіших інструментів :) +По-друге, редактори коду мають спеціалізацію - редагування коду, вони забезпечують вас корисними функціями на зразок кольорової підсвітки коду відповідно його значення або автоматичного закриття дужок. +Пізніше ми побачимо як це працює. Незабаром свій старий вірний редактор коду ви сприйматимете як один зі своїх улюблених інструментів. :) \ No newline at end of file diff --git a/uk/css/README.md b/uk/css/README.md old mode 100755 new mode 100644 index 26c0c08e382..ace84122e58 --- a/uk/css/README.md +++ b/uk/css/README.md @@ -4,43 +4,41 @@ ## Що таке CSS? -Каскадні таблиці стилів (англ. Cascading Style Sheets, скорочено CSS) - спеціальна мова, що використовується для опису зовнішнього вигляду і форматування сайту написаного мовою розмітки (як HTML). Сприймайте це, як свого роду макіяж для нашої веб-сторінки;). +Каскадні таблиці стилів (CSS) - це мова, яка використовується для опису вигляду та форматування веб-сайту, написаного на мові розмітки (наприклад, HTML). Розгляньте це як макіяж для нашої веб-сторінки. ;) -Але ми ж не хочемо починати знову все з нуля, правда? А візьмемо знову щось, що вже було створене програмістами і опубліковано в Інтернеті для вільного користування. Ви ж знаєте, знову винаходити велосипед зовсім не весело. +Але ми не хочемо починати з нуля, чи не так? Ще раз повторюємо: ми будемо використовувати те, що програмісти випускають в Інтернеті безкоштовно. Ви знаєте, що винаходити велосипед не весело. ## Скористаємось Bootstrap! -Bootstrap - один з найбільш популярних HTML і CSS фреймворків для розробки прекрасних веб-сайтів: https://getbootstrap.com/ +Bootstrap - це один з найпопулярніших HTML-і CSS фреймворків для розробки гарних веб-сайтів: https://getbootstrap.com/ -Він був написаний програмістами, які працювали для Twitter'у і на сьогоднішній день удосконалюється волонтерами з усього світу. +Цей фреймворк був написаний програмістами, які працювали у Twitter. Тепер він розробляється волонтерами з усього світу! -## Встановлення Boostrap +## Встановлюємо Boostrap -Для встановлення Bootstrap, вам потрібно додати наступні рядки у розділ `` вашого `.html` файлу (`blog/templates/blog/post_list.html`): +Для встановлення Bootstrap, відкрийте файл `.html` у редакторі коду і додайте наступний код в секцію ``»: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html - - + ``` -Це не додасть жодного файлу до вашого проекту. Натомість ці рядки просто вказують на файли опубліковані в інтернеті. -Просто рухайтесь вперед, відкрийте ваш веб-сайт і оновіть сторінку. Ось так! +Це не додасть жодного файлу до вашого проекту. Натомість ці рядки просто вказують на файли опубліковані в інтернеті. Отже далі просто, відкрийте свій веб-сайт і оновіть сторінку. Ось так! ![Рисунок 14.1](images/bootstrap1.png) -Вже краще! - +Виглядає набагато краще! ## Статичні файли в Django -Нарешті, ми детальніше розглянемо те, що ми називали __статичними файлами__. Статичні файли включають усі ваші CSS файли та картинки - файли, які не є динамічними, а отже, їхній вміст не залежить від змісту запиту і буде однаковим для усіх користувачів. - +Нарешті, ми детальніше розглянемо те, що ми називали **статичними файлами**. Статичні файли - це всі ваші CSS файли та зображення. Їх зміст не залежить від контексту запиту і буде однаковим для кожного користувача. ### Де помістити статичні файли для Django -Як ви бачили, коли ми запускали `collectstatic` на сервері, Django вже знає, де знайти статичні файли для вбудованого додатку "admin". Тепер нам просто потрібно додати деякі статичні файли для нашого власного додатку `blog`. +Як ви бачили, коли ми запускали collectstatic на сервері, Django вже знає, де знайти статичні файли для вбудованого додатку "admin". Тепер нам просто потрібно додати деякі статичні файли для нашого власного додатку, `blog`. -Створимо директорію `static` всередині додатку blog: +Створимо директорію з ім’ям `static` всередині додатку blog: djangogirls ├── blog @@ -48,118 +46,130 @@ Bootstrap - один з найбільш популярних HTML і CSS фре │ ├── static │   └── templates └── mysite + -Django автоматично знайде всі "статичні" папки всередині будь-якої з папок з вашими додатками, і він буде мати можливість використовувати їх як статичні файли. - - +Django автоматично знайде всі папки, які називаються "статичними", в папках з будь-якими вашими додатками, і він буде мати можливість використовувати їх вміст як статичні файли. ## Ваш перший CSS файл! -Що ж, тепер давайте створимо CSS файл для того, щоб додати ваш власний стиль до вашої веб-сторінки. Створіть нову папку з назвою `css` всередині вашої папки `static`. Потім всередині цієї папки`css` створіть новий файл `blog.css`. Готові? +Що ж, тепер створімо CSS файл для того, щоб додати ваш власний стиль до вашої вебсторінки. Створіть нову папку з назвою `css` всередині вашої папки `static`. Потім всередині папки `css` створіть новий файл з назвою `blog.css`. Готові? djangogirls └─── blog └─── static └─── css └─── blog.css + -Настав час написати CSS! Відкрийте файл `static/css/blog.css` в редакторі коду. +Настав час написати CSS! Відкрийте файл `static/css/blog.css` в вашому редакторі коду. -Не будемо тут занурюватись надто глибоко в процес налаштування і вивчення CSS, оскільки це так просто, що ви можете вивчити цей матеріал самостійно після завершення воркшопу. Ми наполегливо рекомендуємо пройти курс [Codeacademy HTML & CSS course](https://www.codecademy.com/tracks/web) для того, щоб вивчити все, що вам потрібно знати про оформлення веб-сайтів за допомогою CSS. +Ми не будемо занурюватись тут надто глибоко в процес налаштування і вивчення CSS. Ми рекомендуємо безкоштовний CSS-курс в кінці цієї сторінки, якщо ви бажаєте вивчити більше. -Але принаймні попрацюємо трохи. Може ми могли б змінити колір заголовка? -Щоб зрозуміти кольори, комп'ютери використовують спеціальні коди. Вони починаються з `#` і далі слідують 6 літер (A-F), а також цифри (0-9). Ви можете знайти коди кольорів, наприклад, тут: http://www.colorpicker.com/. Також можете користуватися вже [визначеними кольорами](http://www.w3schools.com/colors/colors_names.asp), такими як `red` та `green`. +Але давайте зробимо хоча б трохи. Можливо, ми могли б змінити колір заголовків? Щоб зрозуміти кольори, комп'ютери використовують спеціальні коди. Ці коди починаються з `#` та складаються з шести літер (A-F) та цифр (0-9). Наприклад, код синього кольору `#0000FF`. Ви можете знайти інші коди тут: http://www.colorpicker.com/. Також можете користуватися вже [визначеними кольорами ](http://www.w3schools.com/colors/colors_names.asp), такими як `red` та `green`. У вашому файлі `static/css/blog.css` потрібно додати наступний код: +{% filename %}blog/static/css/blog.css{% endfilename %} + ```css -h1 a { - color: #FCA205; +h1 a, h2 a { + color: #C25100; } + ``` -`h1 a` - CSS селектор. Це означає, що ми застосовуємо наші стилі до кожного елементу `a` всередині елементу `h1` (наприклад, коли ми маємо в коді щось на зразок: `

link

`). У цьому випадку, ми повідомляємо про те, що треба змінити колір на `#FCA205`, тобто помаранчевий. Звичайно, ви можете визначити тут ваш власний колір! +`h1 a` - це CSS селектор. Він означає, що ми застосовуємо наші стили до усіх тегів `a` всередині тега `h1`; для селектора `h2 a` ми робимо теж саме для тегів в `h2`. Отже, в прикладі `

link

`, `h1 a` стиль буде використаний. У цьому випадку ми повідомляємо про зміну кольору на `#C25100`, тобто на темно-помаранчевий. Ви можете встановити свій колір тут, але переконайтеся, що він буде на контрасті з білим фоном! -В CSS файлі ми визначаємо стилі для елементів файлу HTML. Елементи ідентифікуються іменами (тобто `a`, `h1`, `body`), атрибутом `class` або атрибутом `id`. -Class і id - імена, які ви присвоюєте елементам власноруч. Класи (сlasses) визначають групи елементів, а ідентифікатори (id), в свою чергу, вказують на специфічні елементи. Наприклад, наступний тег може бути ідентифікований CSS з використанням тегового імені `a`, класу `external_link`, або ідентифікатора `link_to_wiki_page`: +В CSS файлі ми визначаємо стилі для елементів файлу HTML. Перший спосіб - це ідентифікувати елементи за ім'ям. Ви можете пам'ятати з розділу HTML, що такі елементи називаються тегами. Такі речі як `a`, `h1`, та `body` - це приклади імен елементів. Ми також можемо ідентифікувати елементи по атрибуту `class` або по атрибуту `id`. Class і id -- це імена, які ви присвоюєте елементам власноруч. Класи (сlasses) визначають групи елементів, а ідентифікатори (id), в свою чергу, вказують на конкретні елементи. Наприклад, ви можете ідентифікувати наступний елемент за ім'ям `a`, класом `external_link`, або ідентифікатором(id) `link_to_wiki_page`: ```html ``` -Читайте про [CSS селектори на w3schools](http://www.w3schools.com/cssref/css_selectors.asp). +Ви можете прочитати більше про [ CSS Селектори на w3schools](http://www.w3schools.com/cssref/css_selectors.asp). + +Також нам треба повідомити нашому HTML шаблону, що ми додали CSS. Для цього відкрийте `blog/templates/blog/post_list.html` файл в редакторі коду та додайте наступний рядок на початку цього файлу: -Далі, нам треба повідомити наш HTML-шаблон про те, що ми додали CSS. Відкрийте файл `blog/templates/blog/post_list.html` і додайте на початок цей рядок: +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html {% load static %} ``` -Тут лише завантажуються статичні файли :) -Далі, між `` і ``, після посилань на CSS файли Bootstrap додайте цей рядок: +Тут ми лише завантажуємо статичні файли. :) Між тегами `` та `` , після посилань на файли Bootstrap CSS, додайте наступний рядок: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html ``` -Браузер читає файли в порядку їх слідування, тому ми повинні впевнитись, що код написаний в правильному місці. Інакше, код в нашому файлі може перекривати код із файлів Bootstrap. -Ми щойно повідомили наш шаблон, де розташовані наші CSS файли. + +Браузер читає файли у тому порядку, в якому вони надані, тому ми повинні переконатися, що цей код знаходиться в правильному місці. В іншому випадку код у нашому файлі може заміненим кодом з файлів Bootstrap. Ми щойно повідомили нашому шаблону де розташован наш CSS файл. Тепер ваш файл має виглядати наступним чином: +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + ```html {% load static %} + Django Girls blog - - + -
+

Django Girls Blog

-
+ {% for post in posts %} -
-

published: {{ post.published_date }}

-

{{ post.title }}

+
+ +

{{ post.title }}

{{ post.text|linebreaksbr }}

-
+ {% endfor %} ``` -Добре, збережіть файл і перезавантажте сторінку! +OK, збережіть файл і перезавантажте сторінку! ![Рисунок 14.2](images/color2.png) Чудова робота! Можливо, ми також хотіли б дати нашому веб-сайту трохи повітря і збільшити відступ зліва? Давайте спробуємо! +{% filename %}blog/static/css/blog.css{% endfilename %} + ```css body { padding-left: 15px; } ``` -Додайте це до вашого CSS, збережіть файл і подивіться, як це працює! +Додайте цей код до вашого CSS файлу, збережіть цей файл і подивіться як це працює! ![Рисунок 14.3](images/margin2.png) -Може ми могли б також налаштувати шрифт нашого заголовка? Вставте це всередину розділу `` файлу `blog/templates/blog/post_list.html`: +Можливо, ми могли б також налаштувати шрифт нашого заголовка? Вставте це всередину розділу `` файлу `blog/templates/blog/post_list.html`: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html - + ``` -Цей рядок імпортує шрифт із назвою *Lobster* із колекції шрифтів Google (https://www.google.com/fonts). +Як і раніше, перевірте порядок і місце перед посиланням на `blog/static/css/blog.css`. Цей рядок імпортує шрифт під назвою *Lobster* з шрифтів Google (https://www.google.com/fonts). -Знайдіть блок визначення стилю `h1 a` (код між фігурними дужками `{` і `}`) в CSS файлі `blog/static/css/blog.css`. Тепер додайте Тепер додайте рядок `font-family: 'Lobster';` між дужками і перезавантажте сторінку: +Знайдіть де оголошений блок `h1 a` (код між дужками `{` та `}`) у файлі CSS `blog/static/css/blog.css`. Тепер додайте рядок `font-family: 'Lobster';` між дужками та перезавантажте сторінку: + +{% filename %}blog/static/css/blog.css{% endfilename %} ```css -h1 a { - color: #FCA205; +h1 a, h2 a { + color: #C25100; font-family: 'Lobster'; } ``` @@ -168,52 +178,61 @@ h1 a { Чудово! +Як було зазначено вище, CSS має свою концепцію класів. Це дозволяє Вам іменувати частини HTML коду та застосовувати стилі лише до цих частин коду не впливаючи на інші частини. Це може бути дуже корисним! Можливо, у вас можуть бути два тега div, які виконують щось різне (наприклад ваш заголовок та пост). Клас може допомогти вам зробити їх різними. -Як було зазначено вище, CSS має концепцію класів. Вона дозволяє вам іменувати частину HTML коду і застосовувати стилі лише до цієї частини без будь-якого ефекту на інші частини. Це буває надзвичайно корисним. Скажімо, у вас є два блоки div, але вони виконують зовсім різні функції (як ваш заголовок і пост). Клас дозволяє вам зробити їх вигляд різним. +Наступним кроком треба дати ім'я деяким сніппетам HTML коду. Для цього треба замінити `header` , що містить ваш заголовок наступним чином: -Дайте імена певним частинам HTML коду. Додайте клас `page-header` до блоку `div`, що містить ваш заголовок, як це зроблено тут: +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html - + ``` -А тепер додайте клас `post` до вашого блоку `div`, що містить сам допис. +А тепер додайте клас `post` до вашого `article`, що містить пост блога. + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html -
-

published: {{ post.published_date }}

-

{{ post.title }}

+
+ +

{{ post.title }}

{{ post.text|linebreaksbr }}

-
+ ``` -А тепер додамо визначення блоків для різних селекторів. Селектори, які починаються із символу `.` стосуються класів. Існує багато хороших посібників і пояснень CSS у Вебі, що можуть допомогти вам зрозуміти наступний код. Поки що, просто скопіюйте і вставте це у ваш файл `mysite/static/css/blog.css`: +А тепер ми додамо визначаючі блоків різним селекторам. Селектори, які починають із символу `.` стосуються класів. В Інтернеті існує багато гарних туторіалів та пояснень, як працювати з CSS, які можуть допомогти Вам зрозуміти наступний код. Поки що, скопіюйте і вставте цей код у ваш файл `blog/static/css/blog.css` + +{% filename %}blog/static/css/blog.css{% endfilename %} ```css .page-header { - background-color: #ff9400; + background-color: #C25100; margin-top: 0; + margin-bottom: 40px; padding: 20px 20px 20px 40px; } -.page-header h1, .page-header h1 a, .page-header h1 a:visited, .page-header h1 a:active { +.page-header h1, +.page-header h1 a, +.page-header h1 a:visited, +.page-header h1 a:active { color: #ffffff; font-size: 36pt; text-decoration: none; } -.content { - margin-left: 40px; -} - -h1, h2, h3, h4 { +h1, +h2, +h3, +h4 { font-family: 'Lobster', cursive; } .date { - float: right; color: #828282; } @@ -221,11 +240,14 @@ h1, h2, h3, h4 { float: right; } -.post-form textarea, .post-form input { +.post-form textarea, +.post-form input { width: 100%; } -.top-menu, .top-menu:hover, .top-menu:visited { +.top-menu, +.top-menu:hover, +.top-menu:visited { color: #ffffff; float: right; font-size: 26pt; @@ -236,53 +258,73 @@ h1, h2, h3, h4 { margin-bottom: 70px; } -.post h1 a, .post h1 a:visited { +.post h2 a, +.post h2 a:visited { color: #000000; } + +.post > .date, +.post > .actions { + float: right; +} + +.btn-secondary, +.btn-secondary:visited { + color: #C25100; + background: none; + border-color: #C25100; +} + +.btn-secondary:hover { + color: #FFFFFF; + background-color: #C25100; +} ``` -Далі обгорніть HTML код, що відображає пости, визначеннями класів. Замініть це: +Далі модифікуйте HTML код який відображує пости використовуючи визначення класів. Замініть: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html {% for post in posts %} -
-

published: {{ post.published_date }}

-

{{ post.title }}

+
+ +

{{ post.title }}

{{ post.text|linebreaksbr }}

-
+ {% endfor %} ``` в `blog/templates/blog/post_list.html` на: +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + ```html -
+
-
+
{% for post in posts %} -
-
-

published: {{ post.published_date }}

-
-

{{ post.title }}

+
+ +

{{ post.title }}

{{ post.text|linebreaksbr }}

-
+ {% endfor %}
-
+
``` -Збережіть ці файли і перезавантажте веб-сайт. +Збережіть файли і перезавантажте свій сайт. ![Рисунок 14.4](images/final.png) -Юхууу! Виглядає прекрасно, чи не так? -Код, який ми щойно вставили, насправді не є складним для розуміння і ви в змозі зрозуміти більшу його частину після прочитання. - -Не бійтеся трохи повозитися з цим CSS файлом і спробуйте поміняти деякий код. Якщо щось зламається, не хвилюйтесь, ви завжди можете відмінити попередню дію! +Клас! Виглядає чудово, чи не так? Подивіться на цей код, який ми щойно вставили, щоб знайти місця де ми додали класи у HTML файл і використали їх у CSS файлі. Щоб б ви змінили у коді, якби ви хотіли, щоб дата відображалася бірюзового кольору? -В будь-якому разі, дуже рекомендуємо пройти цей безкоштовний онлайн [Codeacademy HTML & CSS курс](https://www.codecademy.com/tracks/web). Він допоможе вам вивчити усе, що потрібно знати про оформлення веб-сайтів за допомогою CSS. +Не бійтеся трохи поекспериментувати з цим CSS файлом, спробуйте щось змінити в ньому. Експерименти з CSS файлом можуть допомогти вам краще зрозуміти, що роблять різні частини коду. Якщо ви щось зламаєте, не хвилюйтеся - ви завжди можете повернутися до попередньої версії! -Готові до наступного розділу?! :) +Ми дійсно рекомендуємо пройти безкоштовні онлайн-курси "Basic HTML & HTML5" та "Basic CSS" на [freeCodeCamp](https://learn.freecodecamp.org/). Ці курси можуть допомогти вам дізнатись як зробити ваші сайти більш привабливими використовуючи HTML та CSS. +Готові до наступного розділу?! :) \ No newline at end of file diff --git a/uk/deploy/README.md b/uk/deploy/README.md old mode 100755 new mode 100644 index 8f35a4db6c9..d939f2bb0d0 --- a/uk/deploy/README.md +++ b/uk/deploy/README.md @@ -1,22 +1,18 @@ # Розгортання! -> **Зауваження** Цей розділ може бути дещо складним для освоєння. Наполегливо продовжуйте і дійдіть до кінця; розгортання - важлива частина процесу розробки веб-сайту. Цей розділ розташований посередині посібника, щоб ваш наставник зміг допомогти із дещо хитрим процесом випуску веб-сайту в Інтернет. Це означає, що ви все ще можете завершити цей курс самостійно, якщо раптом не встигаєте. +> **Зауваження** Цей розділ інколи може бути дещо складним для освоєння. Наполегливо продовжуйте і дійдіть до кінця; розгортання -- важлива частина процесу розробки веб-сайту. Цей розділ розташований посередині посібника, щоб ваш наставник зміг допомогти із дещо хитрим процесом випуску веб-сайту в Інтернет. Це означає, що ви все ще можете завершити цей курс самостійно, якщо раптом не встигаєте. -До цього часу ваш веб-сайт був доступний лише локально на вашому комп'ютері, тепер ви дізнаєтесь, як його розгорнути! Розгортання - це процес публікації вашого додатку в Інтернеті таким чином, що люди можуть зайти і побачити його :). +До цього часу, ваш вебсайт бул лише на вашому комп’ютері. Тепер прийшов час навчитися як розгорнути його (задеплоїти)! Розгортання -- це процес публікації вашого додатку в Інтернеті таким чином, що люди можуть зрештою зайти і побачити його. :) -Як ви вже знаєте, веб-сайт має бути розміщений на сервері. В Інтернеті є багато компаній які пропонують такі послуги. Ми будемо використовувати той, який має відносно простий розгортання процес: [PythonAnywhere](https://www.pythonanywhere.com/). PythonAnywhere безкоштовний для малих додатків, в яких не дуже багато користувачів, тож нам цього точно буде достатньо. +Як ви вже знаєте, веб-сайт має бути розміщений на сервері. В Інтернеті є багато хостингів (server providers), ми ж будемо використовувати [PythonAnywhere](https://www.pythonanywhere.com/). PythonAnywhere безкоштовний для малих додатків, в яких не дуже багато користувачів, тож нам цього точно буде достатньо. Інший зовнішній інструмент, який ми будемо використовувати - це [GitHub](https://www.github.com), платформа для розміщення коду. У нього є альтернативи, але майже кожен програміст зараз має GitHub профіль, і скоро ви будете серед них! -Ці три місця є дуже важливими для вас. Ваш локальний комп'ютер буде місцем, де ви розробляєте і тестуєте. Після того, як впевнитесь в змінах, ви перемістите копію програми на GitHub. Веб-сайт буде на PythonAnywhere і ви оновите його, роблячи нову копію коду з GitHub. +These three places will be important to you. Your local computer will be the place where you do development and testing. When you're happy with the changes, you will place a copy of your program on GitHub. Your website will be on PythonAnywhere and you will update it by getting a new copy of your code from GitHub. # Git -Git - це "система контролю версій", яка використовується багатьма розробниками. Ця програма дозволяє відслідковувати зміни у файлах з часом так, що ви можете повернутись до певних версій пізніше. Схоже на функцію "слідкувати за змінами" в Microsoft Word, але набагато потужніше. - -## Встановлення Git - -> **Примітка** Якщо ви вже виконали процес встановлення, немає потреби робити це ще раз, - можете перейти до наступного кроку і почати створення свого Git репозиторію. +> **Note** If you already did the [installation steps](../installation/README.md), there's no need to do this again – you can skip to the next section and start creating your Git repository. {% include "/deploy/install_git.md" %} @@ -24,285 +20,162 @@ Git - це "система контролю версій", яка викорис Git відслідковує зміни певних файлів в репозиторії коду (коротко – "репо"). Давайте створимо "репо" для нашого проекту. Відкрийте вашу консоль та запустіть наступні команди в папці `djangogirls`: -> **Примітка** Перевірте поточну директорію за допомогою команд `pwd` (OSX/Linux) або `cd` (Windows) перед стартом репозиторію. Ви маєте бути в папці `djangogirls`. +> **Note** Check your current working directory with a `pwd` (Mac OS X/Linux) or `cd` (Windows) command before initializing the repository. Ви маєте бути в папці `djangogirls`. + +{% filename %}command-line{% endfilename %} $ git init Initialized empty Git repository in ~/djangogirls/.git/ $ git config --global user.name "Your Name" $ git config --global user.email you@example.com + -Створення git-репозиторію відбувається тільки один раз на кожен проект (і тобі більше не потрібно буде заново вводити ім'я чи електронну пошту). +Initializing the git repository is something we need to do only once per project (and you won't have to re-enter the username and email ever again). -Git стежитиме за змінам всіх файлів у цій директорії, але є певні файли, які ми хочемо ігнорувати. Ми зробимо це шляхом створення файлу з назвою `.gitignore` в базовій директорії. Відкрий свій редактор і створи новий файл з наступним змістом: +### Adjusting your branch name -``` -*.pyc -__pycache__ -myvenv -db.sqlite3 -/static -.DS_Store -``` +If the version of Git that you are using is older than **2.28**, you will need to change the name of your branch to "main". To determine the version of Git, please enter the following command: -І збережи його як `.gitignore` в директорії "djangogirls". +{% filename %}command-line{% endfilename %} -> **Примітка** Крапка на початку імені файлу важлива! У разі виникнення будь-яких труднощів при створенні (наприклад, Mac не любить, коли через Finder створюють файли, імена яких починаються з крапки), використовуйте "Зберегти як" у редакторі, це повинно спрацювати. + $ git --version + git version 2.xx... + -> **Примітка** Одним із файлів, вказаних в `.gitignore` є `db.sqlite3`. Цей файл є вашою локальною базою даних, де зберігаються пости. Ми не хочемо додавати його до нашого репозиторію, тому що веб-сайт на PythonAnywhere використовуватиме іншу базу. Ця база даних може бути SQLite, як на вашій локальній машині, але зазвичай, ми будемо використовувати базу MySQL, яка може обслуговувати набагато більше відвідувачів сайту, ніж SQLite. У всякому разі, ігнорування бази даних SQLite для копії коду на GitHub, означає, що всі створені вами пости залишаться і будуть доступні локально, але ви можете додати їх також і на продакшн. Ви повинні думати про локальну базу як про хороший майданчик, де можна тестувати різні речі і не боятися, що можна видалити реальні пости з блогу. +Only if the second number of the version, shown as "xx" above, is less than 28, will you need to enter the following command to rename your branch. If it is 28 or higher, please continue to "Ignoring files". As in "Initializing", this is something we need to do only once per project, as well as only when your version of Git is less than 2.28: -Перед тим, як виконати команду `git add` (також, коли ви просто не впевненні що змінилось) непоганою ідеєю буде виконати `git status`. Це допоможе уникнути сюрпризів, наприклад, додавання чи коміту небажаного файлу. Команда `git status` повертає інформацію про файли у вашому репозиторії: untracked (не додані до репозиторію файли), modified (змінені файли), staged (файл додані до коміту), статус поточної гілки і багато іншого. Вивід повинен бути схожий на: +{% filename %}command-line{% endfilename %} - $ git status - On branch master + $ git branch -M main + - No commits yet +### Ignoring files + +Git will track changes to all the files and folders in this directory, but there are some files we want it to ignore. We do this by creating a file called `.gitignore` in the base directory. Open up your editor and create a new file with the following contents: + +{% filename %}.gitignore{% endfilename %} + # Python + *.pyc + *~ + __pycache__ + + # Env + .env + myvenv/ + venv/ + + # Database + db.sqlite3 + + # Static folder at project root + /static/ + + # macOS + ._* + .DS_Store + .fseventsd + .Spotlight-V100 + + # Windows + Thumbs.db* + ehthumbs*.db + [Dd]esktop.ini + $RECYCLE.BIN/ + + # Visual Studio + .vscode/ + .history/ + *.code-workspace + + +And save it as `.gitignore` in the "djangogirls" folder. + +> **Примітка** Крапка на початку імені файлу важлива! У разі виникнення будь-яких труднощів при створенні (наприклад Mac не любить коли створюють файли, імена яких починаються з крапки через Finder), тоді використати "Зберегти як" у редакторі, це повинно спрацювати. І впевніться, що не додали `.txt`, `.py` або будь-які інші розширення до імені файлу. Для Git потрібно саме назва `.gitignore`, так він її розпізнає. Linux and MacOS treat files with a name that starts with `.` (such as `.gitignore`) as hidden and the normal `ls` command won't show these files. Instead use `ls -a` to see the `.gitignore` file. +> +> **Note** One of the files you specified in your `.gitignore` file is `db.sqlite3`. That file is your local database, where all of your users and posts are stored. We'll follow standard web programming practice, meaning that we'll use separate databases for your local testing site and your live website on PythonAnywhere. The PythonAnywhere database could be SQLite, like your development machine, but usually you will use one called MySQL which can deal with a lot more site visitors than SQLite. Either way, by ignoring your SQLite database for the GitHub copy, it means that all of the posts and superuser you created so far are going to only be available locally, and you'll have to create new ones on production. You should think of your local database as a good playground where you can test different things and not be afraid that you're going to delete your real posts from your blog. + +It's a good idea to use a `git status` command before `git add` or whenever you find yourself unsure of what has changed. This will help prevent any surprises from happening, such as wrong files being added or committed. The `git status` command returns information about any untracked/modified/staged files, the branch status, and much more. The output should be similar to the following: + +{% filename %}command-line{% endfilename %} + + $ git status + On branch main + + No commits yet + Untracked files: (use "git add ..." to include in what will be committed) - + .gitignore blog/ manage.py mysite/ - + requirements.txt + nothing added to commit but untracked files present (use "git add" to track) + -Зрештою, зберігаємо наші зміни. Перейдіть до консолі і виконайте наступні команди: +And finally we save our changes. Go to your console and run these commands: - $ git add --all . +{% filename %}command-line{% endfilename %} + + $ git add . $ git commit -m "My Django Girls app, first commit" [...] 13 files changed, 200 insertions(+) create mode 100644 .gitignore [...] create mode 100644 mysite/wsgi.py + + +## Pushing your code to GitHub +Go to [GitHub.com](https://www.github.com) and sign up for a new, free user account. (If you already did that in the workshop prep, that is great!) Be sure to remember your password (add it to your password manager, if you use one). -## Викладемо наш код на GitHub +Then, create a new repository, giving it the name "my-first-blog". Leave the "initialize with a README" checkbox unchecked, leave the .gitignore option blank (we've done that manually) and leave the License as None. -Відкриємо [GitHub.com](https://www.github.com) і створимо новий безкоштовний обліковий запис. (Ті хто зробили це ще на етапі підготовки - справжні молодці!) +![](images/new_github_repo.png) -Створимо новий репозиторій з назвою "my-first-blog". Залишимо опцію "initialise with a README" не вибраною, .gitignore порожньою (пізніше ми додамо це вручну) і License також залишимо як None. +> **Note** The name `my-first-blog` is important – you could choose something else, but it's going to occur lots of times in the instructions below, and you'd have to substitute it each time. It's probably easier to stick with the name `my-first-blog`. - +On the next screen, you'll be shown your repo's clone URL, which you will use in some of the commands that follow: -> **Примітка** Ім'я `my-first-blog` важливе - ви можете вибрати щось інше, але воно буде використовуватись багато разів в інструкціях нижче, і потрібно буде замінити його кожного разу. Мабуть легше просто його залишити як `my-first-blog`. +![](images/github_get_repo_url_screenshot.png) -В наступному екрані ми побачимо посилання для клонування репозиторію - clone URL, скопіюємо його і вставимо у термінал: +Now we need to hook up the Git repository on your computer to the one up on GitHub. - +Type the following into your console (replace `` with the username you entered when you created your GitHub account, but without the angle-brackets -- the URL should match the clone URL you just saw). -Зараз нам потрібно під'єднати Git репозиторій на локальному комп'ютері до щойно створеного на GitHub. +{% filename %}command-line{% endfilename %} -Введіть у вашій консолі (замінивши `<ваше-github-ім'я>` іменем користувача, вказаним під час створення облікового запису GitHub, але без кутових дужок): + $ git remote add origin https://github.com//my-first-blog.git + $ git push -u origin main + - $ git remote add origin https://github.com/<ваше-github-ім'я>/my-first-blog.git - $ git push -u origin master +When you push to GitHub, you'll be asked for your GitHub username and password (either right there in the command-line window or in a pop-up window), and after entering credentials you should see something like this: -Введемо наше ім'я користувача та пароль від GitHub, і побачимо щось на зразок: +{% filename %}command-line{% endfilename %} - Username for 'https://github.com': hjwp - Password for 'https://hjwp@github.com': Counting objects: 6, done. Writing objects: 100% (6/6), 200 bytes | 0 bytes/s, done. Total 3 (delta 0), reused 0 (delta 0) - To https://github.com/hjwp/my-first-blog.git - * [new branch] master -> master - Branch master set up to track remote branch master from origin. - - - -Ваш код тепер на GitHub. Ходімо перевіримо! Виявляється, він у хорошій компанії - [Django](https://github.com/django/django), [Цей посібник](https://github.com/DjangoGirls/tutorial) і багато інших чудових проектів з відкритим вихідним кодом також публікуються на GitHub :) - - -# Налаштування нашого блогу на PythonAnywhere - -> **Примітка** Можливо, ви вже створили обліковий запис на PythonAnywhere під час підготовки - якщо це так, немає необхідності робити це знову. - -{% include "/deploy/signup_pythonanywhere.md" %} - - -## Завантажимо наш код на PythonAnywhere - -Після входу до PythonAnywhere, ми опинимось на головній панелі або сторінці "Consoles". Виберемо опцію почати нову "bash" консоль (Start a new console - bash) - це PythonAnywhere версія консолі, схожа на ту, що на вашому комп'ютері. - -> **Примітка** PythonAnywhere побудований на основі Linux, тому, якщо ви на Windows, консоль буде трохи відрізнятись від тієї, що на вашому комп'ютері. - -Давайте завантажимо наш код з GitHub у PythonAnywhere, клонувавши наш репозиторій. Наберіть наступне у консолі PythonAnywhere (не забудьте використовувати ім'я користувача GitHub замість `< ваше-github-ім'я>`): - - $ git clone https://github.com/<ваше-github-ім'я>/my-first-blog.git - -Ця команда завантажить копію вашого коду на PythonAnywhere. Давайте перевіримо, набравши `tree my-first-blog`: - - $ tree my-first-blog - my-first-blog/ - ├── blog - │ ├── __init__.py - │ ├── admin.py - │ ├── migrations - │ │ ├── 0001_initial.py - │ │ └── __init__.py - │ ├── models.py - │ ├── tests.py - │ └── views.py - ├── manage.py - └── mysite - ├── __init__.py - ├── settings.py - ├── urls.py - └── wsgi.py - - -### Створення virtualenv на PythonAnywhere - -Так само як і на власному комп'ютері, створіть virtualenv на PythonAnywhere. У консолі Bash введіть: - -``` -$ cd my-first-blog - -$ virtualenv --python=python3.4 myvenv -Running virtualenv with interpreter /usr/bin/python3.4 -[...] -Installing setuptools, pip...done. - -$ source myvenv/bin/activate - -(mvenv) $ pip install django whitenoise -Collecting django -[...] -Successfully installed django-1.8.2 whitenoise-2.0 -``` - - -> **Примітка** Крок `pip install` може зайняти кілька хвилин. Терпіння і ще раз терпіння! Але якщо він займає більш ніж 5 хвилин, щось пішло шкереберть. Попросіть допомоги у вашого тренера. - - - - -### Збирання статичних файлів. - -Можливо ви поцікавились, що за штука цей "whitenoise"? Це інструмент для обслуговування так званих "статичних файлів". Статичні файли - це файли, які зазвичай не змінюються і не виконують ніякого коду, наприклад, HTML чи CSS файли. На серверах вони працюють інакше, ніж на вашому локальному комп'ютері, щоб сервер міг їх віддавати, нам потрібен спеціальний інструмент, такий як "whitenoise". - -Пізніше, коли ми змінимо CSS для нашого сайту, ми дізнаємось трохи більше про статичні файли. - -Поки що нам просто потрібно виконати додаткову команду `collectstatic` на сервері. Ця команда каже Django про усі статичні файли на сервері, які йому потрібні. На даний момент це в основному файли, що допомагають зробити красивою сторінку адміністрування. - - (mvenv) $ python manage.py collectstatic - - You have requested to collect static files at the destination - location as specified in your settings: - - /home/edith/my-first-blog/static - - This will overwrite existing files! - Are you sure you want to do this? - - Type 'yes' to continue, or 'no' to cancel: yes - -Введемо "yes" і помчали! Чи не прекрасно, коли ми можемо змусити комп'ютер друкувати незрозумілий текст сторінка за сторінкою? Кожного разу я додаю невеликий звуковий супровід: дир-дир-дир... - - Copying '/home/edith/my-first-blog/mvenv/lib/python3.4/site-packages/django/contrib/admin/static/admin/js/actions.min.js' - Copying '/home/edith/my-first-blog/mvenv/lib/python3.4/site-packages/django/contrib/admin/static/admin/js/inlines.min.js' - [...] - Copying '/home/edith/my-first-blog/mvenv/lib/python3.4/site-packages/django/contrib/admin/static/admin/css/changelists.css' - Copying '/home/edith/my-first-blog/mvenv/lib/python3.4/site-packages/django/contrib/admin/static/admin/css/base.css' - 62 static files copied to '/home/edith/my-first-blog/static'. - - -### Створимо базу даних на PythonAnywhere - -Ось ще одна річ, яка відрізняється на локальному комп'ютері і на сервері: вони використовують різні бази даних. Так що облікові записи користувачів і статті блогу можуть відрізнятися на сервері і локальному комп'ютері. - -Ми можемо ініціалізувати базу даних на сервері таким самим чином, як і на локальному комп'ютері - з допомогою `migrate` і `createsuperuser`: - - - (mvenv) $ python manage.py migrate - Operations to perform: - [...] - Applying sessions.0001_initial... OK - - - (mvenv) $ python manage.py createsuperuser - - -## Опублікуємо наш блог як веб-додаток - -Тепер наш код на PythonAnywhere, віртуальне середовище готове, статичні файли зібрані, база даних встановлена. Ми готові до публікації веб-додатку! - -Перейдемо до панелі керування PythonAnywhere, натиснувши на лого сайту і виберемо вкладку **Web**. Тепер натиснемо **Add a new web app**. - -Після підтвердження нашого доменного імені, виберемо ручне налаштування (**manual configuration**) у діалоговому вікні, зверніть увагу: варіант "Django" нам *не годиться*. Далі виберемо **Python 3.4** і натиснемо Next для завершення. - -> **Примітка** Пересвідчіться, що ви вибрали варіант "Manual configuration", а не "Django". Ми занадто круті для стандартних налаштувань PythonAnywhere для Django ;-) - - -### Налаштуємо virtualenv - -Ми опинились на сторінці налаштувань веб-додатку на PythonAnywhere. Сюди слід переходити, якщо ви хочете зробити якісь зміни до додатку на сервері. - - - - -У розділі "Vitrualenv" натиснемо на червоний текст "Enter the path to a virtualenv" (введіть шлях до virtualenv) і напишемо: `/home//my-first-blog/myvenv/`. Перед тим, як продовжити, натиснемо синю кнопку з галочкою, щоб зберегти шлях. - -> **Примітка** Замініть на своє ім'я користувача. Якщо ви помилитесь, PythonAnywhere покаже вам невеличке попередження. - - -### Сконфігуруємо WSGI файл - -Django використовує у роботі "WSGI протокол" - стандарт взаємодії веб-додатків на Python із веб-серверами. Він підтримується PythonAnywhere. Отже, поредагувавши конфігураційний файл WSGI, ми дозволимо PythonAnywhere розпізнати наш блог на Django. - -Перейдемо за посиланням напроти "WSGI configuration file" (у розділі "Code" близько до початку сторінки - посилання матиме якусь таку назву: `/var/www/_pythonanywhere_com_wsgi.py`). Ми опинились на сторінці з редактором. - -Зітремо весь вміст файлу і замінимо його таким: - -```python -import os -import sys - -path = '/home//my-first-blog' # use your own username here -if path not in sys.path: - sys.path.append(path) - -os.environ['DJANGO_SETTINGS_MODULE'] = 'mysite.settings' - -from django.core.wsgi import get_wsgi_application -from whitenoise.django import DjangoWhiteNoise -application = DjangoWhiteNoise(get_wsgi_application()) -``` - -> **Примітка** Не забудьте вказати своє ім'я користувача замість `` -> **Примітка** Третій рядок вказує PythonAnywhere, як знайти наш додаток. Дуже важливо, щоб цей шлях був коректним і щоб не було зайвих пробілів. Інакше ви побачите "ImportError" в логах помилок. - -Завдання цього файлу - розповісти PythonAnywhere, де живе наш веб-додаток і як знайти файл із налаштуванням Django. Також він налаштовує інструмент для статичних файлів "whitenoise". - -Натиснемо **Save** і перейдемо назад до вкладки **Web**. - -Готово! Натискаємо на велику зелену **Reload** кнопку і можемо глянути на свій веб-додаток. Посилання на нього вгорі сторінки. - - -## Підказки для відлагодження (debug) - -Якщо відвідавши ваш сайт, побачили повідомлення про помилку, найперше, куди слід подивитись - це **лог помилок**. Перейти до нього можна із [вкладки Web](https://www.pythonanywhere.com/web_app_setup/) PythonAnywhere. Гляньте, чи є там повідомлення про помилки; найновіші будуть внизу файлу. Найчастіше трапляються такі проблеми: - -- Забули ввести одну із команд у консолі: створення віртуального середовища, його активацію, встановлення туди Django, збирання статичних файлів, міграцію бази даних. - -- Зробили опечатку в шляху до virtualenv на вкладці Web - в такому разі, там можна буде побачити маленьке червоне повідомлення про помилку. - -- Помилились у конфігураційному файлі WSGI - перевірте шлях до своєї директорії my-first-blog. - -- Ви точно вибрали таку ж версію Python для віртуального середовища, як і для веб-додатку? Обидві повинні мати версію 3.4. - -- Ось деякі [загальні підказки для налагодження у PythonAnywhere вікі](https://www.pythonanywhere.com/wiki/DebuggingImportError). - -Пам'ятайте, що ваш тренер може допомогти! + To https://github.com/ola/my-first-blog.git + + * [new branch] main -> main + Branch main set up to track remote branch main from origin. + + -# Ми вийшли у світ! +Your code is now on GitHub. Go and check it out! You'll find it's in fine company – [Django](https://github.com/django/django), the [Django Girls Tutorial](https://github.com/DjangoGirls/tutorial), and many other great open source software projects also host their code on GitHub. :) -На сторінці за замовчуванням нашого сайту має бути напис "Welcome to Django" так само, як і на вашому локальному комп'ютері. Спробуємо додати `admin` у кінці URL і опинимось у панелі адміністратора. Використаємо для входу логін і пароль та побачимо, що тут можна додавати нові пости на сервер. +{% include "/deploy/pythonanywhere.md" %} +# Check out your site! -*ДОБРЯЧЕ* похваліть себе! Розгортання на сервер - один з найхитромудріших етапів веб-розробки. Зазвичай люди витрачають дні, щоб усе запрацювало. Але вам вдалось вийти у справжній інтернет, запросто! +The default page for your site should say "It worked!", just like it does on your local computer. Try adding `/admin/` to the end of the URL, and you'll be taken to the admin site. Log in with the username and password, and you'll see you can add new Posts on the server -- remember, the posts from your local test database were not sent to your live blog. +Once you have a few posts created, you can go back to your local setup (not PythonAnywhere). From here you should work on your local setup to make changes. This is a common workflow in web development – make changes locally, push those changes to GitHub, and pull your changes down to your live Web server. This allows you to work and experiment without breaking your live Web site. Pretty cool, huh? +Give yourself a *HUGE* pat on the back! Server deployments are one of the trickiest parts of web development and it often takes people several days before they get them working. But you've got your site live, on the real Internet! \ No newline at end of file diff --git a/uk/deploy/install_git.md b/uk/deploy/install_git.md index cd11f616a69..4156f616175 100644 --- a/uk/deploy/install_git.md +++ b/uk/deploy/install_git.md @@ -1,28 +1,83 @@ +Git - це "система контролю версій", яка використовується багатьма розробниками. Ця програма дозволяє відслідковувати зміни до файлів з часом так, що ви можете повернутись до певних версій пізніше. A bit like the "track changes" feature in word processor programs (e.g., Microsoft Word or LibreOffice Writer), but much more powerful. -### Windows +## Встановлення Git -Git можна завантажити з [git-scm.com](https://git-scm.com/). Ви можете натискати "next next next" на всіх кроках окрім одного. На п’ятому кроці, названому "Adjusting your PATH environment", виберіть "Run Git and associated Unix tools from the Windows command-line" (нижня опція). Крім цього, стандартні налаштування добрі. Вимкніть закінчення рядків в стилі Windows, ввімкніть в стилі Unix, вони кращі. + -### Mac OS +Ви можете завантажити Git з [git-scm.com](https://git-scm.com/). You can hit "next" on all steps except for two: in the step where it asks to choose your editor, you should pick Nano, and in the step entitled "Adjusting your PATH environment", choose "Use Git and optional Unix tools from the Windows Command Prompt" (the bottom option). Крім цього, стандартні налаштування добрі. Вимкніть закінчення рядків в стилі Windows, ввімкніть в стилі Unix, вони кращі. -Завантажте Git з [git-scm.com](https://git-scm.com/) і просто слідуйте вказівкам. +During installation, if you are presented with the option of "Adjusting the name of the initial branch in new repositories", please choose to "Override the default" and use "main". This will align your installation of Git with the broad direction of the global developer community, and the "main" branch will be used through the remainder of this tutorial. Please see https://sfconservancy.org/news/2020/jun/23/gitbranchname/ and https://github.com/github/renaming for further discussion of this subject. +Do not forget to restart the command prompt or PowerShell after the installation finished successfully. -### Linux + -Якщо Git не встановлений, то він має бути доступний через менеджер пакетів, тому спробуйте: +Download Git from [git-scm.com](https://git-scm.com/) and follow the instructions. +During installation, if you are presented with the option of "Adjusting the name of the initial branch in new repositories", please choose to "Override the default" and use "main". This will align your installation of Git with the broad direction of the global developer community, and the "main" branch will be used through the remainder of this tutorial. Please see https://sfconservancy.org/news/2020/jun/23/gitbranchname/ and https://github.com/github/renaming for further discussion of this subject. -#### Debian або Ubuntu +> **Note** If you are running OS X 10.6, 10.7, or 10.8, you will need to install the version of git from here: [Git installer for OS X Snow Leopard](https://sourceforge.net/projects/git-osx-installer/files/git-2.3.5-intel-universal-snow-leopard.dmg/download) - $ sudo apt install git + + -#### Fedora +{% filename %}command-line{% endfilename %} - $ sudo dnf install git +```bash +$ sudo apt install git +``` +### Adjusting your default branch name -#### openSUSE +This will align your installation of Git with the broad direction of the global developer community, and the "main" branch will be used through the remainder of this tutorial. Please see https://sfconservancy.org/news/2020/jun/23/gitbranchname/ and https://github.com/github/renaming for further discussion of this subject. - $ sudo zypper install git +{% filename %}command-line{% endfilename %} + + $ git config --global --add init.defaultBranch main + + + + + + +{% filename %}command-line{% endfilename %} + +```bash +$ sudo dnf install git +``` + +### Adjusting your default branch name + +This will align your installation of Git with the broad direction of the global developer community, and the "main" branch will be used through the remainder of this tutorial. Please see https://sfconservancy.org/news/2020/jun/23/gitbranchname/ and https://github.com/github/renaming for further discussion of this subject. + +{% filename %}command-line{% endfilename %} + + $ git config --global --add init.defaultBranch main + + + + + + +{% filename %}command-line{% endfilename %} + +```bash +$ sudo zypper install git +``` + +### Adjusting your default branch name + +This will align your installation of Git with the broad direction of the global developer community, and the "main" branch will be used through the remainder of this tutorial. Please see https://sfconservancy.org/news/2020/jun/23/gitbranchname/ and https://github.com/github/renaming for further discussion of this subject. + +{% filename %}command-line{% endfilename %} + + $ git config --global --add init.defaultBranch main + + + \ No newline at end of file diff --git a/uk/deploy/pythonanywhere.md b/uk/deploy/pythonanywhere.md new file mode 100644 index 00000000000..d3d63ae6ae4 --- /dev/null +++ b/uk/deploy/pythonanywhere.md @@ -0,0 +1,88 @@ +# Setting up our blog on PythonAnywhere + +## Sign up for a PythonAnywhere account + +> **Note** You might have already created a PythonAnywhere account earlier during the install steps – if so, no need to do it again. +> +> {% include "/deploy/signup_pythonanywhere.md" %} + + +## Configuring our site on PythonAnywhere + +Go back to the main [PythonAnywhere Dashboard](https://www.pythonanywhere.com/) by clicking on the logo, and choose the option to start a "Bash" console – that's the PythonAnywhere version of a command line, just like the one on your computer. + +![The 'New Console' section on the PythonAnywhere web interface, with a button for 'bash'](images/pythonanywhere_bash_console.png) + +> **Note** PythonAnywhere is based on Linux, so if you're on Windows, the console will look a little different from the one on your computer. Deploying a web app on PythonAnywhere involves pulling down your code from GitHub, and then configuring PythonAnywhere to recognise it and start serving it as a web application. There are manual ways of doing it, but PythonAnywhere provides a helper tool that will do it all for you. Let's install it first: + +{% filename %}PythonAnywhere command-line{% endfilename %} +``` +$ pip{{ book.pa_py_version }} install --user pythonanywhere +``` + +That should print out some things like `Collecting pythonanywhere`, and eventually end with a line saying `Successfully installed (...) pythonanywhere- (...)`. + +Now we run the helper to automatically configure our app from GitHub. Type the following into the console on PythonAnywhere (don't forget to use your GitHub username in place of ``, so that the URL matches the clone URL from GitHub): + +{% filename %}PythonAnywhere command-line{% endfilename %} +``` +$ pa_autoconfigure_django.py --python={{ book.pa_py_version }} https://github.com//my-first-blog.git +``` + +As you watch that running, you'll be able to see what it's doing: + +- Downloading your code from GitHub +- Creating a virtualenv on PythonAnywhere, just like the one on your own computer +- Updating your settings file with some deployment settings +- Setting up a database on PythonAnywhere using the `manage.py migrate` command +- Setting up your static files (we'll learn about these later) +- And configuring PythonAnywhere to serve your web app via its API + +On PythonAnywhere all those steps are automated, but they're the same steps you would have to go through with any other server provider. + +The main thing to notice right now is that your database on PythonAnywhere is actually totally separate from your database on your own computer, so it can have different posts and admin accounts. As a result, just as we did on your own computer, we need to initialize the admin account with `createsuperuser`. PythonAnywhere has automatically activated your virtualenv for you, so all you need to do is run: + +{% filename %}PythonAnywhere command-line{% endfilename %} +``` +(ola.pythonanywhere.com) $ python manage.py createsuperuser +``` + +Type in the details for your admin user. Best to use the same ones as you're using on your own computer to avoid any confusion, unless you want to make the password on PythonAnywhere more secure. + +Now, if you like, you can also take a look at your code on PythonAnywhere using `ls`: + +{% filename %}PythonAnywhere command-line{% endfilename %} +``` +(ola.pythonanywhere.com) $ ls +blog db.sqlite3 manage.py mysite requirements.txt static +(ola.pythonanywhere.com) $ ls blog/ +__init__.py __pycache__ admin.py apps.py migrations models.py +tests.py views.py +``` + +You can also go to the "Files" page and navigate around using PythonAnywhere's built-in file browser. (From the Console page, you can get to other PythonAnywhere pages from the menu button in the upper right corner. Once you're on one of the pages, there are links to the other ones near the top.) + + +## You are now live! + +Your site should now be live on the public Internet! Click through to the PythonAnywhere "Web" page to get a link to it. You can share this with anyone you want. :) + + +> **Note** This is a beginners' tutorial, and in deploying this site we've taken a few shortcuts which aren't ideal from a security point of view. If and when you decide to build on this project, or start a new project, you should review the [Django deployment checklist](https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/) for some tips on securing your site. + +## Debugging tips + + +If you see an error while running the `pa_autoconfigure_django.py` script, here are a few common causes: + +- Forgetting to create your PythonAnywhere API token. +- Making a mistake in your GitHub URL +- If you see an error saying *"Could not find your settings.py"*, it's probably because you didn't manage to add all your files to Git, and/or you didn't push them up to GitHub successfully. Have another look at the Git section above +- If you previously signed up for a PythonAnywhere account and had an error with collectstatic, you probably have an older version of SQLite (eg 3.8.2) for your account. In that case, sign up for a new account and try the commands in the PythonAnywhere section above. + + +If you see an error when you try to visit your site, the first place to look for some debugging info is in your **error log**. You'll find a link to this on the PythonAnywhere ["Web" page](https://www.pythonanywhere.com/web_app_setup/). See if there are any error messages in there; the most recent ones are at the bottom. + +There are also some [general debugging tips on the PythonAnywhere help site](http://help.pythonanywhere.com/pages/DebuggingImportError). + +And remember, your coach is here to help! diff --git a/uk/deploy/signup_pythonanywhere.md b/uk/deploy/signup_pythonanywhere.md index 12ee7b6ca76..4123c088df3 100644 --- a/uk/deploy/signup_pythonanywhere.md +++ b/uk/deploy/signup_pythonanywhere.md @@ -1,8 +1,19 @@ +"Пайтон всюди" це сервіс для перевірки коду на мові Пайтон у "хмарному" середовищі. Ми використовуватимемо його для розміщення файлів веб-сайту, наживо та в Інтернеті. -Тепер час для створення безкоштовного "Beginner" акаунту на PythonAnywhere. +Ми запустимо блог, котрий написаний на "Пайтон всюди". Зареєструй профіль "Новачка" на "Пайтон всюди" (можна вибрати безкоштовну версію без реєстрації банківської карти). -* [www.pythonanywhere.com](https://www.pythonanywhere.com/) +* [www.pythonanywhere.com ](https://www.pythonanywhere.com/) +![Сторінка реєстрації на "Пайтон всюди", що показує клавішу для створення безкоштовного профілю "Новачка"](../deploy/images/pythonanywhere_beginner_account_button.png) -> **Примітка** При виборі імені користувача, пам'ятайте, що URL-адреса блогу матиме вигляд `yourusername.pythonanywhere.com`, так що зупиніться або на вашому ніку, або на імені, пов'язаному з тематикою блогу. +> **Примітка** При виборі назви користувача пам'ятай, що посилання твого блогу матиме наступний вигляд `назвакористувача.pythonanywhere.com`, тому обирай або своє власне ім'я, або назву тематики свого блогу. При цьому, запам'ятай свій пароль (додай його до свого менеджера паролів, якщо ти таким користуєшся). +## Як створити токен API у "Пайтон всюди" + +Це одноразова дія. Коли зареєструєшся на сайті "Пайтон всюди", завантажиться сторінка робочої панелі. Знайди посилання до своєї "Профільної" сторінки у верхньому правому куті: + +![Посилання на профільну сторінку у верхньому правому кутку](../deploy/images/pythonanywhere_account.png) + +потім вибери закладку "Токен API" та натисни клавішу із повідомленням "Створити новий токен API". + +![Закладка із токеном API на Профільній сторінці](../deploy/images/pythonanywhere_create_api_token.png) \ No newline at end of file diff --git a/uk/django/README.md b/uk/django/README.md old mode 100755 new mode 100644 index 2c30e036c46..302d6edcf50 --- a/uk/django/README.md +++ b/uk/django/README.md @@ -1,27 +1,27 @@ # Що таке Django? -Django (_/ˈdʒæŋɡoʊ/ джанго_) - безкоштовний і відкритий фреймворк для створення веб додатків, написаний мовою програмування Python. Веб фреймворк - набір компонентів, які допомагають розробляти веб-сайти швидше і простіше. +Django (/ˈdʒæŋɡoʊ/ *джан-го*) це безкоштовний та відкритий програмний каркас для створення вебзастосунків, написаний мовою Пайтон. Веб-каркас - це набір компонентів, які допомагають розробляти веб-сайти швидше і простіше. -При побудові веб-сайту, ви завжди потребуєте схожого набору компонентів: спосіб управління авторизацією користувача (створення акаунту, вхід, вихід), панель управління, форми, спосіб завантажити файли, тощо. +При побудові веб-сайту, ви завжди потребуєте схожого набору компонентів: способу управління авторизацією користувача (створення акаунту, вхід, вихід), панелі управління, форм, способу завантажити файли, тощо. -На щастя для вас інші люди вже давно помітили, що веб розробники зіштовхуються з подібними проблемами під час розробки нового сайту, отже вони об'єднались в команду і створили фреймворки (Django є одним з таких), що дають вам вже готові до використання компоненти. +На щастя, вже давно виявлено певні проблеми, із якими зіштовхуються веб-розробники під час написання нового сайту. Тому вони об'єднались та створили програмні каркаси (Джанго як один із них), що забезпечують готові компоненти для використання. -Фреймворки існують для того, щоб вберегти вас від необхідності повторно винаходити велосипед і допомогти зменшити деякі накладні витрати під час розробки нового сайту. +Програмні каркаси були створені для того, щоб вберегти розробників від зайвої роботи та полегшити роботу під час розробки нового сайту. -## Навіщо вам потрібен фреймворк? +## Навіщо вам потрібен цей фреймворк? -Щоб зрозуміти для чого насправді розроблений Django, потрібно ближче розглянути роботу серверу. Першочергово сервер повинен знати про те, що ви бажаєте щоб він обслуговував ваш сайт. +Щоб зрозуміти, для чого насправді створено Джанго, треба ближче розглянути роботу серверів. По-перше, сервер має розуміти, що кінцевим результатом повинна бути веб-сторінка. -Уявіть собі поштову скриньку (порт), котра моніториться на вхідні листи (запити). Це здійснюється веб сервером. Веб сервер читає листа і відсилає відповідь із веб-сторінкою. Але коли ви бажаєте відправити дещо, вам потрібно мати деякий вміст. І Django є інструментом, котрий допомагає вам створити цей контент. +Уявіть собі поштову скриньку (порт), котра моніториться на вхідні листи (запити). Це здійснюється веб сервером. Веб-сервер читає листа, а потім надсилає відповідб із веб-сторінки. Але коли ви бажаєте відправити дещо, вам потрібно мати деякий вміст. І Джанго є інструментом, котрий допомагає вам створити такий контент. ## Що трапляється коли хтось надсилає запит на веб-сайт з вашого серверу? -Коли на веб-сервер надходить запит, він перенаправляється на Django, котрий намагається з'ясувати на що конкретно був запит. Спочатку береться адреса веб-сторінки і Django намагається з'ясувати, що робити. Ця частина роботи здійснюється таким компонентом Django як __urlresolver__ (зауважте, що адреса веб-сайту називається URL - Uniform Resource Locator - отже ім'я *urlresolver* має сенс). Це не дуже складний елемент - вилучається список шаблонів і відбуваються спроби знайти підходящий URL. Django перевіряє шаблони у порядку слідування і якщо якийсь із них відповідає адресі веб-сторінки Django надсилає запит до асоційованої функції (котра має назву *view*). +Коли запит надходить на веб-сервер, він передається до Джанго, котрий намагається з'ясувати, чого насправді стосується запит. Він спочатку використовує адресу веб-сторінки та намагається з'ясувати, що далі робити. Ця частина виконується компонентом **urlresolver** програми Джанго (зверніть увагу, що адреса веб-сторінки називається URL - універсальний відслідковувач ресурсу - тому назва *urlresolver* є цілком виправданою). Такий процес нескладний: компонент використовує список шаблонів та намагається підібрати відповідне посилання. Джанго перевіряє шаблони зверху вниз та, якщо зназодить співпадіння, надсилає запит до пов'язаної функції (котра називається *view*). -Уявіть собі листоношу з листом. Він йде по вулиці і звіряє номер кожного будинку з тим, що вказаний в адресі отримувача. Якщо номер співпадає, він кладе листа в скриньку. Аналогічним чином працює і urlresolver! +Уявіть листоношу з листом. Він йде по вулиці і звіряє номер кожного будинку з тим, що вказаний в адресі отримувача. Якщо номер співпадає, він кладе листа в скриньку. Аналогічним чином працює urlresolver! -Всередині функції *view* відбуваються найцікавіші речі: щоб знайти деяку інформацію, ми можемо подивитися в базу даних. Можливо, користувач може попросити зробити певні зміни даних? На зразок листа, що говорить "Будь ласка, змініть опис моєї роботи." Елемент *view* може перевірити чи дозволено вам це зробити, потім оновлює опис роботи для вас і відправляє зворотнє повідомлення: "Виконано!". Далі блок *view* генерує відповідь і Django може відправити її до веб браузера користувача. +Найцікавіша робота виконується функцією *view*: можна перевірити базу даних щодо якоїсь конкретної інформації. Можливо, користувач надістав запит на зміну певних даних? Як у випадку листа: "Прошу змінити опис моєї роботи". Функція *view* може перевірити, чи користувач має доступ до таких змін, а потім оновити опис роботи та надіслати повідомлення: "Готово!". Потім функція *view* створює відповідь, а Джанго може надіслати її до веб-браузера користувача. -Звичайно, вище наведені пояснення є трохи спрощеними, але вам не потрібно знати усіх технічних деталей поки що. Достатньо мати загальне уявлення. +Опис роботи сервісу, наведений раніше, досить спрощений, але спочатку не потрібно знати усі технічні деталі. Досить володіти і загальною ідеєю. -Отже замість того, щоб надто занурюватись у деталі, ми просто почнемо щось створювати із використанням Django і вивчимо усі важливі складові на цьому шляху! +Отже, замість заглиблюватись у деталі, ми розпочнемо створення чогось за допомогою Джанго та вивчимо усі потрібні частини його роботи поступово! \ No newline at end of file diff --git a/uk/django_admin/README.md b/uk/django_admin/README.md old mode 100755 new mode 100644 index de2e6babcf2..31eb7312a38 --- a/uk/django_admin/README.md +++ b/uk/django_admin/README.md @@ -1,8 +1,10 @@ -# Django адміністратор +# Панель адміністрування Django -Щоб додавати, редагувати і видаляти пости, які ми щойно змоделювали, використаємо Django адміністратор. +Для того, щоб додавати, редагувати і видаляти пости, які ми щойно змоделювали, ми будемо використовувати панель адміністрування Django. -Відкриймо файл `blog/admin.py` і замінимо його зміст на наступні рядки: +Давайте відкриємо файл `blog/admin.py` у редакторі коду і замінимо його вміст на наступне: + +{% filename %}blog/admin.py{% endfilename %} ```python from django.contrib import admin @@ -13,29 +15,43 @@ admin.site.register(Post) Як можна побачити, ми імпортуємо (включаємо) модель посту Post визначену у попередньому розділі. Щоб зробити нашу модель видимою на сторінці адміністратора, потрібно зареєструвати модель за допомогою `admin.site.register(Post)`. -Гаразд, час поглянути на нашу модель Post. Не забудьте виконати в консолі команду `python manage.py runserver` для того щоб запустити сервер. Відкрийте браузер, введіть адресу http://127.0.0.1:8000/admin/ і ви побачите сторінку входу схожу на цю: +Гаразд, час поглянути на нашу модель Post. Не забудьте виконати в консолі команду `python manage.py runserver` для того щоб запустити сервер. Відкрийте браузер і введіть адресу http://127.0.0.1:8000/admin/. Ви побачите сторінку входу яка виглядає наступним чином: ![Сторінка авторизації](images/login_page2.png) -Щоб ввійти, потрібно створити *суперкористувача (superuser)* - користувача, котрий може контролювати все на сайті. Поверніться до командного рядка, наберіть `python manage.py createsuperuser`, і натисніть клавішу Enter. Коли вас про це запитають, введіть логін користувача (маленькими буквами без пропусків), адресу email та пароль. Не хвилюйтеся, що ви не можете бачити пароль який вводите – так і повинно бути. Просто введіть його і натисніть `Enter` щоб продовжити. Вихідний результат має виглядати наступним чином (де ім'я користувача і email повинні містити ваші дані): +Щоб увійти, нам потрібно створити *superuser* (суперкористувача) - обліковий запис користувача, який має контроль над усім, що є на сайті. Поверніться до командного рядка, введіть `python manage.py createsuperuser`і натисніть Enter. + +> Пам'ятайте, що для запису нових команд, поки веб-сервер працює, відкрийте нове вікно терміналу і активуйте Ваше віртуальне середовище (virtualenv). Ми розглядали, як написати нові команди в розділі **Ваш перший Django проект!** в секції **Запуск веб серверу**. + +{% filename %}Mac OS X або Linux:{% endfilename %} (myvenv) ~/djangogirls$ python manage.py createsuperuser - Username: admin - Email address: admin@admin.com + + +{% filename %}Windows:{% endfilename %} + + (myvenv) C:\Users\Name\djangogirls> python manage.py createsuperuser + + +Коли вас про це запитають, введіть ім'я користувача (маленькими буквами без пробелів), адресу електронної пошти та пароль. **Не хвилюйтеся, що ви не можете бачити пароль, який вводите – так повинно бути.** Введіть його і натисніть `Enter` , щоб продовжити. Вихідний результат має виглядати наступним чином (де ім'я користувача і електронна пошта повинні бути вашими власними): + + Username: ola + Email address: ola@example.com Password: Password (again): Superuser created successfully. + Поверніться до вашого браузера і здійсніть вхід використовуючи логін та пароль щойно створеного суперкористувача; ви маєте побачити робочу панель адміністратора Django. -![Django адміністратор](images/django_admin3.png) +![Панель адміністрування Django](images/django_admin3.png) -Перейдіть в Posts та поекспериментуйте з ними трошки. Додайте п’ять-шість постів. Не переживайте за вміст, можете просто скопіювати якийсь текст з цього підручника щоб зберегти час :). +Перейдіть до постів і трохи поекспериментуйте з ними. Додайте 5-6 постів до блогу. Не хвилюйтесь про зміст - його можна побачити лише на локальному комп'ютері — ви можете скопіювати якийсь текст з цього туторіалу, щоб зберегти час. :) -Переконайтесь у тому, що принаймні два або три поста (але не всі) мають встановлену дату публікації. Це стане у нагоді пізніше. +Переконайтесь у тому, що принаймні два або три поста (але не всі) мають встановлену дату публікації. Це стане у нагоді пізніше. -![Django адміністратор](images/edit_post3.png) +![Панель адміністрування Django](images/edit_post3.png) -Якщо бажаєте дізнатися більше про Django admin, гляньте документацію Django: https://docs.djangoproject.com/en/1.11/ref/contrib/admin/ +If you want to know more about Django admin, you should check Django's documentation: https://docs.djangoproject.com/en/3.2/ref/contrib/admin/ -Це напевне гарний час щоб налити кави (чи чаю) чи з’їсти щось щоб перезарядитися. Ви створили свою першу модель Django і заслуговуєте на короткий тайм-аут! +Це напевне гарний час щоб налити кави (чи чаю) чи з’їсти щось щоб перезарядитися. Ви створили свою першу модель Django і заслуговуєте на короткий тайм-аут! \ No newline at end of file diff --git a/uk/django_forms/README.md b/uk/django_forms/README.md old mode 100755 new mode 100644 index e773c22d764..3611e1c063c --- a/uk/django_forms/README.md +++ b/uk/django_forms/README.md @@ -1,8 +1,8 @@ # Django форми -Остання річ, яку б ми хотіли зробити з нашим сайтом, це створити зручний спосіб додавати і редагувати пости. Django адміністратор - це звісно круто, але водночас він є досить складним для налаштування. З формами ми будемо мати абсолютний контроль над нашим інтерфейсом - можемо робити майже усе, що заманеться! +Остання річ, яку б ми хотіли зробити з нашим сайтом це створити зручний спосіб додавати і редагувати пости. Django адміністратор це звісно круто, але водночас він є досить складним для налаштування. За допомогою форм ми матимемо абсолютний контроль над нашим інтерфейсом - ми можемо робити майже все, що тільки можемо собі уявити! -Що тішить стосовно Django форм, так це те, що останні можна визначати як з нуля, так і створювати засобами `ModelForm`, що зберігають результат форми всередині моделі. +Що тішить стосовно Django форм так це те, що останні можна визначати як з нуля так і створювати засобами `ModelForm`, що зберігають результат форми всередині моделі. Це саме те, що нам потрібно: створимо форму для нашої моделі `Post`. @@ -12,8 +12,11 @@ blog └── forms.py + -Добре, відкриємо цей файл і наберемо наступний код: +Гаразд, давайте відкриємо його в редакторі коду і наберемо такий код: + +{% filename %}blog/forms.py{% endfilename %} ```python from django import forms @@ -27,91 +30,115 @@ class PostForm(forms.ModelForm): fields = ('title', 'text',) ``` -Спершу потрібно імпортувати Django форми (`from django import forms`) і, очевидно, нашу модель `Post` (`from .models import Post`). +Спочатку нам потрібно імпортувати форми Django (`from django import forms`) та нашу модель (`from .models import Post`). -`PostForm`, як ви можливо зазначили, це ім'я нашої форми. Ми маємо повідомити Django, що наша форма є `ModelForm` (таким чином Django здійснить для нас певні магічні маніпуляції) і рядок `forms.ModelForm` відповідає за це. +`PostForm`, як ви можливо зазначили, ім'я нашої форми. Нам потрібно сказати Django, що ця форма є `ModelForm` ( тому Django зробить для нас трішки магії ) – ` і рядок.ModelForm` відповідає за це. Далі, у нас є `class Meta`, де ми вказуємо для Django котра з моделей має бути використана для створення форми (`model = Post`). -Зрештою, можемо зазначити, якими полями має закінчуватись наша форма. В даному сценарії ми би хотіли опублікувати такі параметри, як заголовок `title` і зміст `text`, дані про автора `author`, що автоматично встановлюються як дані користувача, який наразі залогінився (тобто ви!), а також дата створення `created_date`, яка автоматично встановлюється при створенні поста (тобто в коді), вірно ж? +Зрештою, можемо зазначити якими полями має закінчуватись наша форма. У цьому сценарії ми хочемо опублікувати такі параметри як заголовок `title` і зміст `text`, дані про автора `author`, що автоматично встановлюються як дані особи, яка наразі увійшла в систему (тобто ви!), а також дата створення `created_date`, яка автоматично встановлюється при створенні публікації (тобто в коді), вірно ж? І це все! Все що нам потрібно тепер зробити це використати форму в блоці *view* і відобразити її в шаблоні. -Отже, знову ми створимо: посилання на сторінку, адресу (URL), вид (view) і шаблон (template). +То ж ще раз ми створимо посилання на сторінку, URL- адресу, вид і шаблон. ## Посилання на сторінку з формою -Час відкрити `blog/templates/blog/base.html`. Додамо лінк всередині блоку `div` із ім'ям `page-header`: +Перед тим, як додати посилання, нам потрібно використати деякі значки, як кнопки для посилання. For this tutorial, download [file-earmark-plus.svg](https://raw.githubusercontent.com/twbs/icons/main/icons/file-earmark-plus.svg) and save it in the folder `blog/templates/blog/icons/` + +> Примітка: для того, щоб завантажити зображення SVG, відкрийте контекстне меню за посиланням (зазвичай натисканням правої кнопки миші) і виберіть "Зберегти посилання як". In the dialog asking you where to save the file, navigate to the `djangogirls` directory of your Django project, and within that to subdirectory `blog/templates/blog/icons/`, and save the file there. + +It's time to open `blog/templates/blog/base.html` in the code editor. Тепер ми можемо використовувати значок файлу в базовому шаблоні наступним чином. У елементі `div` всередині секції `header`, додаємо посилання перед елементом `h1`: + +{% filename %}blog/templates/blog/base.html{% endfilename %} ```html - + + {% include './icons/file-earmark-plus.svg' %} + ``` -Зауважте, що ми хочемо запустити наше нове відображення `post_new`. Клас `"glyphicon glyphicon-plus"` постачається bootstrap темою, яку ми використовуємо, і буде відображати знак плюса. +Зверніть увагу, що ми хочемо назвати наш новий огляд `post_new`. Значок [SVG](https://icons.getbootstrap.com/icons/file-earmark-plus/) представлений [Bootstrap Icons](https://icons.getbootstrap.com/) і він відобразить значок сторінки зі знаком плюс. Ми використовуємо директиву шаблону Django під назвою `include`. Це вводить вміст файлу до шаблону Django. Веббраузер знає, як обробляти цей тип контенту без будь-якої подальшої обробки. + +> Ви можете завантажити всі значки Bootstrap [here](https://github.com/twbs/icons/releases/download/v1.1.0/bootstrap-icons-1.1.0.zip). Розархівуйте файл і скопіюйте всі файли з зображеннями SVG у нову папку `blog/templates/blog/` під назвою `icons`. Таким чином, Ви можете отримати доступ до такої іконки як `pencil-fill.svg`, використовуючи шлях до файлу `blog/templates/blog/icons/pencil-fill.svg` -Після додавання відповідного рядка, ваш html файл має виглядати наступним чином: +Після редагування рядку, Ваш HTML файл повинен виглядати таким чином: + +{% filename %}blog/templates/blog/base.html{% endfilename %} ```html {% load static %} + Django Girls blog - - + - -
+ +
-
+
{% block content %} {% endblock %}
-
+
``` -Після збереження та оновлення сторінки http://127.0.0.1:8000 ви звісно побачите знайому помилку `NoReverseMatch`, правда? +Після зберігання та оновлення сторінки http://127.0.0.1:8000 Ви побачите знайому помилку `NoReverseMatch`. Чи так це насправді? ## URL -Відкриваємо `blog/urls.py` і додаємо рядок: +Відкриваємо `blog/urls.py` у редакторі коду та додаємо рядок: + +{% filename %}blog/urls.py{% endfilename %} ```python - url(r'^post/new/$', views.post_new, name='post_new'), +шлях('post/new/', views.post_new, name='post_new'), ``` -Остаточно код буде виглядати так: +Остаточний код буде виглядати так: + +{% filename %}blog/urls.py{% endfilename %} ```python -from django.conf.urls import url +from django.urls import path from . import views urlpatterns = [ - url(r'^$', views.post_list, name='post_list'), - url(r'^post/(?P[0-9]+)/$', views.post_detail, name='post_detail'), - url(r'^post/new/$', views.post_new, name='post_new'), + path('', views.post_list, name='post_list'), + path('post//', views.post_detail, name='post_detail'), + path('post/new/', views.post_new, name='post_new'), ] ``` -Після оновлення сайту бачимо помилку `AttributeError`, оскільки відображення `post_new` не реалізоване. Давайте додамо цей вид прямо зараз. +After refreshing the site, we see an `AttributeError`, since we don't have the `post_new` view implemented. Let's add it right now. + +## post_new view -## Відображення post_new +Тепер відкриваємо у редакторі коду файл `blog/views.py` і додаємо наступні рядки з рештою рядків `from`: -Час відкрити файл `blog/views.py` і додати наступні рядки: +{% filename %}blog/views.py{% endfilename %} ```python from .forms import PostForm ``` -і функцію для потрібного *відображення*: +And then our *view*: + +{% filename %}blog/views.py{% endfilename %} ```python def post_new(request): @@ -119,46 +146,52 @@ def post_new(request): return render(request, 'blog/post_edit.html', {'form': form}) ``` -Щоб створити нову форму `Post`, нам потрібно викликати функцію `PostForm()` і передати її до шаблону. Повернемося пізніше до цього відображення, а зараз давайте створимо шаблон для форми. +Щоб створити нову форму `Post`, потрібно викликати `PostForm` і перенести її до шаблону. Ми повернемось до цього *зображення* пізніше, а зараз створімо шаблон для форми. ## Шаблон -Нам потрібно створити файл `post_edit.html` у папці `blog/templates/blog`. Щоб створити форму нам знадобиться декілька речей: +Потрібно створити файл `post_edit.html` у дирекції `blog/templates/blog, і відкрити його у редакторі коду. Для того, щоб створити форму, необхідні декілька речей:

+ +
    +
  • Ми маємо відобразити форму. Можемо це зробити, наприклад, за допомогою {% raw %}{{ form.as_p }}`{% endraw %}.
  • + +* Вказаний рядок має бути розміщений всередині тега форми HTML: `
    ...
    `. +* Нам знадобиться кнопка "Зберегти" - `Save`. Створимо її в HTML за допомогою виразу ``. +* І нарешті зразу після відкриття тегу форми `
    ` потрібно додати {% raw %}`{% csrf_token %}`{% endraw %}. Це дуже важливо з міркувань безпеки вашої форми! Якщо ви раптом забудете про цю деталь, Django поскаржиться, коли будете намагатися зберегти форму:
-- нам треба показати форму. Можна, наприклад, зробити це за допомогою простого `{% raw %}{{ form.as_p }}{% endraw %}`. -- верхній рядок має бути розміщений всередині тега HTML для форми: `...` -- нам знадобиться кнопка Зберегти - `Save`. Створимо її в HTML за допомогою: `` -- і нарешті, одразу після відкриваючого тегу `
` ми маємо додати `{% raw %}{% csrf_token %}{% endraw %}`. Це дуже важливо з міркувань безпеки вашої форми! Django наголосить на цьому, якщо ви раптом забудете вказати згадану вказівку і будете намагатися зберегти форму: +![Заборонена сторінка CSFR](images/csrf2.png) -![CSFR Forbidden page](images/csrf2.png) +Добре, розгляньмо як повинен виглядати код HTML у `post_edit.html`: -Добре, отже, давайте подивимось як має виглядати HTML код в `post_edit.html`: +{% filename %}blog/templates/blog/post_edit.html{% endfilename %} ```html {% extends 'blog/base.html' %} {% block content %} -

New post

+

New post

{% csrf_token %} {{ form.as_p }} - +
{% endblock %} ``` -Час перезавантажитись! Йой! Ваша форма відображується! +Час оновити сторінку! Гаразд! Ваша форма відображується! -![New form](images/new_form2.png) +![Нова форма](images/new_form2.png) -Але, одну хвилиночку! Коли ви набираєте щось в полях `title` і `text`, та намагаєтесь зберегти зміни - що ж тоді станеться? +Зачекайте! Коли Ви набираєте щось в полях `title` і `text`, намагаючись зберегти це, то що може статися? -А нічого! Ми знову опинимося на тій самій сторінці, і наш текст зникне... і жодного нового поста. Отже, що ж пішло не так? +Нічого! Ми знову опинимось на цій самій сторінці та наш текст зникне...жодного нового поста також не буде додано. Отже, що пішло не так? -Відповідь: нічого. Мусимо проробити трохи більше роботи з нашим блоком *view*. +Відповідь: нічого. Ми мусимо виконати трохи більше роботи в нашому *view<0>.

## Зберігання форми -Відкрийте `blog/views.py` знову. Наразі все що ми маємо в `post_new` це: +Відкрийте `log/views.py` ще раз у редакторі коду. Наразі все, що ми маємо в `post_new` це: + +{% filename %}blog/views.py{% endfilename %} ```python def post_new(request): @@ -166,9 +199,11 @@ def post_new(request): return render(request, 'blog/post_edit.html', {'form': form}) ``` -Коли ми відправляємо форму, ми потрапляємо в той самий view, але цього разу маємо більше даних в `request`, а якщо точніше - в `request.POST` (ця назва не пов’язана з блогерським терміном "пост", вона пов’язана з тим що ми "постимо" дані). Пам'ятайте, що у файлі HTML наше визначення `
` містило атрибут `method="POST"`? Усі поля форми на даний момент знаходитимуться в `request.POST`. Ви не повинні перейменовувати `POST` на щось інше (лише єдине альтернативне прийнятне значення для атрибуту `method` це `GET`, але ми не маємо часу пояснювати в чому різниця). +Коли відправляємо форму, ми потрапляємо у той самий view, але цього разу маємо трохи більше даних у `request`, точніше в `request.POST` (ця назва не пов'язана з блогерським терміном "пост"; вона стосується того, що ми "постимо" дані). Пам'ятайте, що у файлі HTML, наше визначення `` містило змінну `method="POST"`? Усі поля форми на цей час знаходяться в `request.POST`. Ви не повинні перейменовувати `POST` на щось інше (єдиним дійсним альтернативним значенням для `method` є `GET`, але ми не маємо часу пояснювати в чому проявляється різниця). + +Отже, у нашому *view* ми маємо дві окремі ситуації, які треба обробити: перша, коли ми вперше отримуємо доступ до сторінки й хочемо отримати порожню форму, а друга, коли ми повертаємось до *view* з усіма даними форми, які ми щойно набрали. Таким чином, ми маємо додати умову (використаємо для цього `if`): -Отже, ми маємо дві окремі ситуації, що потребують контролю для нашого блоку вид *view*. Перша: коли ми отримуємо доступ до сторінки вперше і хочемо отримати пусту форму. Друга: коли ми повертаємось назад до виду *view* із усіма нещодавно доданими даними форми. Таким чином, маємо додати умову (використаємо для цього `if`). +{% filename %}blog/views.py{% endfilename %} ```python if request.method == "POST": @@ -177,15 +212,19 @@ else: form = PostForm() ``` -Час заповнити порожнє місце `[...]`. Якщо метод `method` є методом `POST`, тоді ми захочемо створити `PostForm` з даними форми, вірно? Зробимо це за допомогою: +Час заповнити крапки `[...]`. Якщо `method` являє собою `POST`, тоді ми хочемо створити `PostForm` з даними форми, чи не так? Ми зробимо це наступним чином: + +{% filename %}blog/views.py{% endfilename %} ```python form = PostForm(request.POST) ``` -Просто! Наступна річ - перевірити чи коректно заповнена форма (налаштовані усі необхідні поля і не відбулося зберігання жодного некоректного значення). Зробимо це за допомогою `form.is_valid()`. +Наступний крок - перевірити правильність форми (усі обов'язкові поля були встановлені й не з'явилися неправильні значення). Ми робимо це за допомогою `form.is_valid()`. + +Ми перевіряємо чи є форма дійсною, якщо це так, то ми можемо її зберегти! -Ми перевіряємо чи є форма прийнятною і якщо це так, то можемо зберегти її! +{% filename %}blog/views.py{% endfilename %} ```python if form.is_valid(): @@ -195,24 +234,29 @@ if form.is_valid(): post.save() ``` -В основі, маємо тут два моменти: зберігаємо форму за допомогою `form.save` і додаємо автора (оскільки поле автор `author` було відсутнє в `PostForm` і це поле є необхідним!). `commit=False` означає, що ми не хочемо поки що зберігати модель `Post` - ми хочемо спочатку додати ім'я автора. У більшості випадків ви будете користуватися `form.save()` без `commit=False`, але в даному випадку, ми маємо це зробити. -`post.save()` захистить здійснені зміни (додавання автора) і створиться новий блог пост! +В основі, маємо тут два моменти: зберігаємо форму за допомогою `form.save` і додаємо автора (оскільки поле автор `author` було відсутнє в `PostForm` і це поле є необхідним). `commit=False` це означає, що ми не хочемо поки зберігати модель `Post` - спочатку ми хочемо додати ім'я автора. Більшу частину часу Ви будете використовувати `form.save()` без `commit=False`, але у цьому випадку, нам слід застосувати його. `post.save()` збереже зміни (додаючи автора) і створиться новий блог! + +Нарешті, було б чудово, якщо ми могли б відразу переходити на сторінку `post_detail` для щойно створеного допису у блозі, чи не так? Для того, щоб зробити це нам необхідно виконати ще один імпорт: -Зрештою, було б чудово, якби ми могли миттєво переходити на сторінку `post_detail` для щойно створеного допису у блозі, чи не так? Щоб зробити це, нам необхідно виконати ще один імпорт: +{% filename %}blog/views.py{% endfilename %} ```python from django.shortcuts import redirect ``` -Додайте це з самого початку вашого файлу. А тепер можемо сказати: перейти на сторінку `post_detail` для щойно створеного поста. +Додайте це на початку Вашого файлу. Тепер ми можемо сказати, "перейдіть на сторінку `post_detail` для перегляду нової публікації": + +{% filename %}blog/views.py{% endfilename %} ```python return redirect('post_detail', pk=post.pk) ``` -`post_detail` - ім'я виду, до якого ми хочемо перейти. Пам'ятаєте, що цей вид потребує змінної `pk`? Щоб здійснити передачу вище згаданої змінної, скористаємося `pk=post.pk`, де `post` є новим постом! +`post_detail` це назва виду, до якого хочемо перейти. Пам'ятайте, що *view* потребує змінну `pk`? Щоб здійснити передачу вище згаданої змінної, скористаємося `pk=post.pk`, де `post` є новоствореним постом! + +Добре, занадто багато балачок, напевно ми хотіли б побачити як цілком зараз виглядає *view*, чи не так? -Але, щось дуже багато балачок, напевно ми хотіли б побачити, як відображується даний вид наразі в цілому, правда ж? +{% filename %}blog/views.py{% endfilename %} ```python def post_new(request): @@ -229,66 +273,82 @@ def post_new(request): return render(request, 'blog/post_edit.html', {'form': form}) ``` -Подивимося, чи усе працює. Зайдіть на сторінку http://127.0.0.1:8000/post/new/, додайте `title` та `text`, збережіть... і вуаля! Новий блог пост успішно додано і нас автоматично перенаправило на сторінку `post_detail`! +Подивимося, чи це працює. Перейдіть на сторінку http://127.0.0.1:8000/post/new/, додайте `title` і `text`, збережіть і готово! Новий блог пост додано і нас перенаправлено на сторінку `post_detail` ! -Ви могли помітити, що ми встановлюємо дату публікації, перед збереженням поста. Пізніше, ми введемо *кнопку публікації* в **Django Girls Tutorial: Розширте ваш додаток**. +Напевно Ви помітили, що ми встановлюємо дату публікації перед збереженням поста. Згодом, ми представимо *кнопку публікації* в **Django Girls Tutorial: Extensions**. Просто чудово! -> Оскільки ми нещодавно мали справу з інтерфейсом Django адміністратора система наразі вважає, що ми залогінились. Є декілька ситуацій, які могли призвести до того, що ми вийшли з системи (закриття браузера, перезавантаження бази даних тощо). Якщо раптом виявиться, що при створенні поста з'явиться помилка, пов'язана із відсутністю залогіненого користувача, перейдіть на сторінку адміністратора http://127.0.0.1:8000/admin і залогіньтеся знову. Проблему тимчасово буде вирішено. Безповоротне розв'язання проблеми чекає на вас у розділі __Домашня робота: безпека вашого сайту!__ після освоєння головного посібника. +> Оскільки нещодавно ми працювали з інтерфейсом адміністратора Django, система вважає, що ми увійшли в систему. Є декілька ситуацій, які могли призвести до виходу з системи (закриття браузера, перезапуск бази даних тощо). Якщо під час створення допису, Ви помітите, що у Вас з'являються помилки, пов'язані з відсутністю зареєстрованого користувача, перейдіть на сторінку адміністратора http://127.0.0.1:8000/admin й увійдіть знову. Проблему тимчасово буде вирішено. Довгострокове розв'язання проблеми чекає на Вас у розділі **Домашня робота: додаємо безпеки Вашому вебсайту!** після основного туторіалу. -![Logged in error](images/post_create_error.png) +![Помилка входу](images/post_create_error.png) +## Form validation -## Перевірка форми +А тепер ми покажемо Вам наскільки круто використовувати форми Django. Блог пост повинен мати такі поля як `заголовок` і `текст. У нашій моделі Post` ми не зазначили, що ці поля (на відміну від `published_date`) не є обов'язковими, тому Django, за замовчуванням, очікує, що вони будуть встановлені. -А тепер ми покажемо вам, наскільки круто використовувати Django форми. Блог пост повинен мати такі поля як заголовок - `title` і зміст - `text`. В нашій моделі `Post` ми не вказали (на відміну від дати публікації - `published_date`), що ці поля не є необхідними, отже, Django, за замовчуванням, очікує що вони будуть заповнені. +Намагайтесь зберегти форму без `заголовку` й `тексту`. Вгадайте, що відбудеться! -Спробуйте зберегти форму без атрибутів `title` і `text`. Здогадуємось, що трапиться! +![Перевірка заповнення форми](images/form_validation2.png) -![Перевірка форми](images/form_validation2.png) +Django дбає про те, щоб перевірити правильність всіх полів у нашій формі. Хіба це не чудово? -Django турбується про те, щоб усі поля нашої форми були коректно заповнені. Хіба це не круто? +## Edit form +Тепер ми знаємо як додавати новий пост. А якщо ми захочемо відредагувати ту, що вже існує? Це дуже схоже на те, що ми щойно зробили. Давайте швиденько створимо кілька важливих речей. (Якщо Ви не розумієте щось, Вам слід запитати свого наставника або переглянути попередні розділи, оскільки ми вже розглянули всі ці кроки). -## Редагування форми +Спочатку, збережемо значок, який зображає кнопку редагування. Завантажте [pencil-fill.svg](https://raw.githubusercontent.com/twbs/icons/main/icons/pencil-fill.svg) й збережіть його на місце `blog/templates/blog/icons/`. -Тепер ми знаємо як додати нову форму. Та якщо ми раптом захочемо відредагувати вже існуючу? Це дуже схоже на те, що ми щойно проробили. Давайте швидко створимо певні важливі речі (якщо вам щось незрозуміло, ви маєте запитати вашого тренера або ще раз передивитись попередній параграф, оскільки ми вже пройшли усі ці речі). +Відкрийте `blog/templates/blog/post_detail.html` у кодовому редакторі й додайте наступний код всередину елементу `article` : -Відкрийте `blog/templates/blog/post_detail.html` і додайте наступний рядок: +{% filename %}blog/templates/blog/post_detail.html{% endfilename %} -```python - +```html + ``` -таким чином, шаблон буде виглядати подібним чином: +Отже, шаблон буде мати такий вигляд: + +{% filename %}blog/templates/blog/post_detail.html{% endfilename %} ```html {% extends 'blog/base.html' %} {% block content %} -
+
+ {% endblock %} ``` -В `blog/urls.py` додамо цей рядок: +Відкрийте `blog/urls.py` в кодовому редакторі, і додайте цей рядок: + +{% filename %}blog/urls.py{% endfilename %} ```python - url(r'^post/(?P[0-9]+)/edit/$', views.post_edit, name='post_edit'), + path('post//edit/', views.post_edit, name='post_edit'), ``` -Повторно використаємо шаблон `blog/templates/blog/post_edit.html`, отже, остання річ, яка лишилась це відображення.. +Використовуємо повторно шаблон `blog/templates/blog/post_edit.html`, таким чином, останньою відсутньою річчю є *view*. -Давайте відкриємо `blog/views.py` і додамо в самому кінці файлу: +Відкриємо `blog/views.py` у кодовому редакторі й додамо це наприкінці файлу: + +{% filename %}blog/views.py{% endfilename %} ```python def post_edit(request, pk): @@ -306,96 +366,116 @@ def post_edit(request, pk): return render(request, 'blog/post_edit.html', {'form': form}) ``` -Виглядає майже точно так, як і наш вид `post_new`, правда? Не зовсім. Перше: ми передаємо додатковий параметр `pk` з адресного рядку. Наступне: ми отримуємо модель `Post`, яку хотіли б відредагувати як `get_object_or_404(Post, pk=pk)` і потім, при створенні форми ми передаємо цей пост як екземпляр `instance`, коли зберігаємо форму: +Це виглядає майже точно так, як і наш `post_new`, чи не так? Але не зовсім. По-перше, переносимо додатковий параметр `pk` з `URL-адреси`. Наступним кроком, отримуємо модель `Post`, яку хотіли б відредагувати як `get_object_or_404(Post, pk=pk)` і після цього, при створенні форми, переносимо цей пост як `приклад`, при збереженні форми... + +{% filename %}blog/views.py{% endfilename %} ```python form = PostForm(request.POST, instance=post) ``` -а коли ми просто відкриваємо форму з цим постом для редагування: +...а коли просто відкриваємо форму з цим постом для редагування: + +{% filename %}blog/views.py{% endfilename %} ```python form = PostForm(instance=post) ``` -Добре, давайте протестуємо, чи все працює! Перейдімо на сторінку `post_detail`. У верхньому правому кутку має з'явитися кнопка редагування: +Добре, перевіримо чи все працює! Перейдімо на сторінку `post_detail`. У верхньому правому куті має бути кнопка редагування: ![Кнопка редагування](images/edit_button2.png) -Коли ви натиснете на неї, то побачите форму з нашим блог постом: +Коли Ви натисните на неї, Ви побачите форму з нашим блог постом: -![Редагування форми](images/edit_form2.png) +![Редагувати форми](images/edit_form2.png) -Можете вільно змінити заголовок або текст і зберегти зміни! +Ви можете вільно змінювати заголовок або текст і зберегти зміни! -Вітаємо! Ваш додаток стає все більш і більш повним! +Вітаємо! Ваш додаток стає все більш завершеним! -Якщо бажаєте дізнатись більше інформації про форми Django, ознайомтесь із документацією: https://docs.djangoproject.com/en/1.11/topics/forms/ +Якщо Ви хочете дізнатись більше про форми Django, Вам слід ознайомитись із документацією: https://docs.djangoproject.com/en/3.2/topics/forms/ ## Безпека -Створювати нові публікації просто клацаючи на посилання класно! Але зараз, будь-хто хто відвідує ваш сайт, буде здатним опублікувати пост, а ви цього напевне не хочете. Давайте зробимо так що кнопка показується для вас, але не показується для всіх інших. +Можливість створювати нові пости, натискаючи на посилання - це круто! Але тепер, будь-яка людина, яка відвідує Ваш сайт, зможе створити новий блог пост, і, мабуть, це не те, що Ви хотіли б. Зробім так, щоб кнопка була показана для Вас, а не для інших людей. -В `blog/templates/blog/base.html`, знайдіть наш `page-header` `div` і тег посилання який ви додали туди раніше. Вони повинні виглядати якось так: +У кодовому редакторі відкрийте `blog/templates/blog/base.html`, знайдіть `div` всередині `header` і тег посилання, який Ви додали туди раніше. Це має виглядати так: + +{% filename %}blog/templates/blog/base.html{% endfilename %} ```html - + + {% include './icons/file-earmark-plus.svg' %} + ``` -Ми збираємось додати інший тег `{% if %}` який показуватиме посилання лише користувачам які ввійшли від імені адміністратора. На даний момент, це лише ви! Змініть тег `` щоб він виглядав так: +Ми збираємось додати до цього інший тег `{% if %}`, який буде показувати посилання тільки тим користувачам, які ввійшли від імені адміністратора. Саме зараз, це Ви! Змініть елемент ``, щоб він виглядав так: + +{% filename %}blog/templates/blog/base.html{% endfilename %} ```html {% if user.is_authenticated %} - + + {% include './icons/file-earmark-plus.svg' %} + {% endif %} ``` -Цей `{% if %}` зробить так, що посилання буде відправлятись браузеру лише коли користувач, що запитував сторінку, залогований. Це не захищає від створення нових публікацій анонімами повністю, але це непоганий перший крок. Ми розглянемо більше питань безпеки в розширених уроках. +`{% if %}` зробить так, що посилання будуть відправлятися браузеру тільки, якщо користувач, що запитує сторінку, увійшов у систему. Це не повністю захищає від створення нових публікацій, але це хороший перший крок. Ми розглянемо більше питань, пов'язаних з безпекою, в розширених уроках. -Пам'ятаєте іконку редагування, що ми додали до нашої сторінки з деталями посту? Ми також хочемо додати цю ж зміну сюди, щоб інші люди не могли редагувати існуючі пости. +Пам'ятайте, що значок редагування, який ми щойно додали на сторінку деталей? Ми також хотіли б додати таку ж зміну сюди, щоб інші люди не мали змоги редагувати пости, що вже існують. -Відкрийте `blog/templates/blog/post_detail.html` і знайдіть: +Відкрийте `log/templates/blog/post_detail.html` у кодовому редакторі й знайдіть наступний рядок: + +{% filename %}blog/templates/blog/post_detail.html{% endfilename %} ```html - + + {% include './icons/pencil-fill.svg' %} + ``` -Замініть це на: +Змініть його на цей: + +{% filename %}blog/templates/blog/post_detail.html{% endfilename %} ```html {% if user.is_authenticated %} - + + {% include './icons/pencil-fill.svg' %} + {% endif %} ``` -Оскільки ви ввійшли до системи, то якщо оновите сторінку, не побачите зміни. Відкрийте сторінку в новому браузері або в анонімному вікні, і тоді ви побачите, що посилання не показується! +Оскільки Ви, скоріше за все, увійшли в систему, якщо Ви оновите сторінку, то не побачите ніяких змін. Завантажте сторінку в іншому браузері або вікні анонімного перегляду (яке називається "InPrivate" у Windows Edge), однак, Ви побачите, що посилання і значок не відображаються! ## Ще одне: розгортання! -Давайте поглянемо, чи це все працює на PythonAnywhere. Час для ще одного розгортання! +Погляньмо чи все працює на PythonAnywhere. Час для ще одного розгортання! -* Спершу, закомітьте новий код і зробіть push на GitHub +* Спочатку зафіксуйте свій новий код і зробіть його на GitHub: -``` -$ git status -$ git add --all . -$ git status -$ git commit -m "Added views to create/edit blog post inside the site." -$ git push -``` +{% filename %}command-line{% endfilename %} -* Тоді, в [bash консолі PythonAnywhere](https://www.pythonanywhere.com/consoles/): + $ git status + $ git add . + $ git status + $ git commit -m "Додано подання для створення / редагування публікації в блозі сайту." + $ git push + -``` -$ cd my-first-blog -$ source myvenv/bin/activate -(myvenv)$ git pull -[...] -(myvenv)$ python manage.py collectstatic -[...] -``` +* Тоді, в [bash консолі PythonAnywhere](https://www.pythonanywhere.com/consoles/): + +{% filename %}PythonAnywhere command-line{% endfilename %} + + $ cd ~/.pythonanywhere.com + $ git pull + [...] + -* Нарешті, перейдіть на [вкладку Web](https://www.pythonanywhere.com/web_app_setup/) і натисніть **Reload**. +(Не забудьте замінити `` Вашим актуальним субдоменом PythonAnywhere, без кутових дужок.) +* Нарешті, перейти на сторінку ["Web"](https://www.pythonanywhere.com/web_app_setup/) ( використати кнопку меню у верхньому правому куті консолю ) та натисніть **Перезавантажити**. Оновіть свій https://subdomain.pythonanywhere.com блог, щоб почати зміни. -І це все! Вітання :) +На цьому все! Вітаємо! :) \ No newline at end of file diff --git a/uk/django_installation/README.md b/uk/django_installation/README.md index 3d6a14afbfb..cbc744e033c 100644 --- a/uk/django_installation/README.md +++ b/uk/django_installation/README.md @@ -1,6 +1,7 @@ # Встановлення Django -> **Зауваження:** Якщо ви вже проходили кроки інсталяції, значить все має бути зроблено - можете переходити зразу до наступного розділу! - -{% include "/django_installation/instructions.md" %} +> **Примітка** Якщо Ви використовуєте Chromebook, пропустіть цей розділ і переконайтеся, що Ви дотримуєтеся інструкцій [Chromebook Setup](../chromebook_setup/README.md). +> +> **Примітка** Якщо Ви вже пройшли через [кроки установки](../installation/README.md), Ви вже впорались з цим – можете відразу переходити до наступної глави! +{% include "/django_installation/instructions.md" %} \ No newline at end of file diff --git a/uk/django_installation/instructions.md b/uk/django_installation/instructions.md index a00cfbf684f..5915caf3df7 100644 --- a/uk/django_installation/instructions.md +++ b/uk/django_installation/instructions.md @@ -1,102 +1,229 @@ -> Частина цього розділу базується на матеріалах Geek Girls Carrots (https://github.com/ggcarrots/django-carrots). - -> Частина цього розділу базується на матеріалі [django-marcador tutorial] -(http://django-marcador.keimlink.de/), -який ліцензований Creative Commons Attribution-ShareAlike 4.0 International License. -Авторське право на навчальні матеріали django-marcador tutorial належить Markus Zapke-Gründemann та ін. - +> Частина цього розділу базується на туторіалах Geek Girls Carrots (https://github.com/ggcarrots/django-carrots). +> +> Частина цієї секції базується на матеріалі [django-marcador tutorial](http://django-marcador.keimlink.de/), який є ліцензованим Creative Commons Attribution-ShareAlike 4.0 International License. Авторське право на навчальні матеріали django-marcador tutorial належить Markus Zapke-Gründemann та ін. ## Віртуальне середовище -Перед тим, як встановлювати Django, ми допоможемо вам встановити надзвичайно корисний інструмент, що допоможе підтримувати середовище розробки на вашому комп'ютері чистим. Цей крок можна пропустити, але дуже рекомендується його виконати. Починати найкращим можливим способом дозволить уникнути багатьох клопотів в майбутньому! +Перед тим як встановлювати Django, ми допоможемо вам встановити надзвичайно корисний інструмент, що допоможе підтримувати середовище розробки на вашому комп'ютері чистим. Цей крок можна пропустити, але дуже рекомендується його виконати. Починати найкращим можливим способом дозволить уникнути багатьох клопотів в майбутньому! + +Отже, створимо віртуальне середовище (англ. **virtual environment** або скорочено *virtualenv*). Virtualenv ізолюватиме ваше Python/Django середовище, для кожного проекту. Це означає, що будь-які зміни, внесені на одному сайті не вплинуть на будь-які інші, які ви також розробляєте. Гарно, правда ж? -Отже, створимо віртуальне середовище (англ. **virtual environment**, скорочено *virtualenv*). Virtualenv ізолюватиме ваше Python/Django середовище, для кожного проекту. Це означає, що будь-які зміни, внесені на одному сайті не вплинуть на будь-які інші, які ви також розробляєте. Гарно, правда ж? +Все що вам необхідно зробити це знайти місце, де ви хочете створити віртуальне середовище `virtualenv`; наприклад, ваша домашня папка. На Windows, це може виглядати як `C:\Users\Name` (де `Name` є Вашим логіном). -Все, що вам необхідно зробити - це знайти місце, де ви хочете створити віртуальне середовище `virtualenv`; наприклад, ваша домашня папка. На Windows це може виглядати як `C:\Users\Name` (де `Name` - ваш логін). +> **ПРИМІТКА** на Windows, переконайтеся, що цей каталог не містить акцентованих або спеціальних символів; якщо ім'я користувача охоплює акцентовані символи, використайте інший каталог, наприклад, `C:\djangogirls`. В рамках цього навчального посібника будемо використовувати нову директорію `djangogirls` з вашої домашньої папки: - mkdir djangogirls - cd djangogirls +{% filename %}command-line{% endfilename %} + + $ mkdir djangogirls + $ cd djangogirls + Створимо віртуальне середовище з ім'ям `myvenv`. Загальна команда буде ось в такому форматі: - python3 -m venv myvenv +{% filename %}command-line{% endfilename %} -### Windows + $ python -m venv myvenv + -Щоб створити нове віртуальне середовище `virtualenv`, вам потрібно відкрити консоль (ми вже розповідали вам про це в одному з попередніх розділів - пам'ятаєте?) і запустити `C:\Python34\python -m venv myvenv`. Це буде виглядати так: + - C:\Users\Name\djangogirls> C:\Python34\python -m venv myvenv +Щоб створити нове `віртуальне середовище`, потрібно відкрити командний рядок і запустити `python -m venv myvenv`. Це буде виглядати так: -де `C:\Python34\python` - це папка, в якій ви перед цим встановили Python, а `myvenv` - ім'я вашого віртуального середовища `virtualenv`. Ви можете використовувати будь-яке ім’я, але старайтесь обмежитись маленькими буквами і не використовуйте пробілів, наголосів або спеціальних символів. Тримати ім’я коротким - також гарна ідея, оскільки ви будете часто посилатися на нього! +{% filename %}command-line{% endfilename %} -### Linux та OS X + C:\Users\Name\djangogirls> python -m venv myvenv + -Створення віртуального середовища `virtualenv` як на Linux так і на OS X просто відбувається запуском `python3 -m venv myvenv`. -Виглядає це так: +Де `myvenv` являє собою назву вашого `віртуального середовища`. Ви можете використовувати будь-яке ім’я, але старайтесь обмежитись маленькими буквами і не використовуйте пробілів, наголосів або спеціальних символів. Мати коротке ім'я - також гарна ідея, оскільки Ви будете часто посилатися на нього! - $ python3 -m venv myvenv + -`myvenv` - ім'я вашого віртуального середовища `virtualenv`. Можете використовувати яке завгодно ім'я, але воно має містити лише маленькі літери і не містити пробілів. Тримати ім’я коротким - також гарна ідея, оскільки ви будете часто посилатися на нього! + -> __ЗАУВАЖЕННЯ:__ Ініціалізація віртуального середовища на Ubuntu 14.04 і Debian 8 схожим методом наразі призводить до наступної помилки: +Ми можемо створити `віртуальне середовище` як на Linux, так і на OS X, запускаючи `python3 -m venv myvenv`. Це буде мати такий вигляд: -> Error: Command '['/home/eddie/Slask/tmp/venv/bin/python3', '-Im', 'ensurepip', '--upgrade', '--default-pip']' returned non-zero exit status 1 +{% filename %}command-line{% endfilename %} -> Щоб обійти цю проблему, використовуйте натомість команду `virtualenv`. + $ python -m venv myvenv + -> $ sudo apt install python-virtualenv -> $ virtualenv --python=python3.4 myvenv +`myvenv` - ім'я вашого віртуального середовища `virtualenv`. Можете використовувати яке завгодно ім'я, але воно має містити лише маленькі літери і не містити пробілів. It is also a good idea to keep the name short as you'll be referencing it a lot! +> **ПРИМІТКА** У деяких версіях Debian/Ubuntu, Ви можете отримати таку помилку: +> +> {% filename %}command-line{% endfilename %} +> +> The virtual environment was not created successfully because ensurepip is not available. On Debian/Ubuntu systems, you need to install the python3-venv package using the following command. +> apt install python3-venv +> You may need to use sudo with that command. After installing the python3-venv package, recreate your virtual environment. +> +> +> У такому випадку, дотримуйтесь наведених вище інструкцій і встановіть пакет `python3-venv`: {% filename %}command-line{% endfilename %} +> +> $ sudo apt install python3-venv +> +> +> **ПРИМІТКА** У деяких версіях Debian/Ubuntu створення такого віртуального середовища, призводить до наступної помилки: +> +> {% filename %}command-line{% endfilename %} +> +> Error: Command '['/home/eddie/Slask/tmp/venv/bin/python3', '-Im', 'ensurepip', '--upgrade', '--default-pip']' returned non-zero exit status 1 +> +> +> Щоб обійти цю проблему, використовуйте натомість команду `virtualenv`. +> +> {% filename %}command-line{% endfilename %} +> +> $ sudo apt install python-virtualenv +> $ virtualenv --python=python{{ book.py_version }} myvenv +> +> +> **ПРИМІТКА:** Якщо Ви отримаєте повідомлення про помилку, наприклад +> +> {% filename %}command-line{% endfilename %} +> +> E: Unable to locate package python3-venv +> +> +> Після цього запустіть: +> +> {% filename %}command-line{% endfilename %} +> +> sudo apt install python{{ book.py_version }}-venv +> + + ## Робота з віртуальним середовищем -Вище зазначена команда створить папку `myvenv` (або інше вибране вами ім'я), що міститиме наше віртуальне середовище (в основному, набір папок і файлів). +Вищезазначена команда створить каталог під назвою `myvenv` (або інша вибрана Вами назва), що буде містити наше віртуальне середовище (в основному, набір каталогів і файлів). + + -#### Windows +Запустіть своє віртуальне середовище виконавши: -Запустіть своє віртуальне середовище, виконавши: +{% filename %}command-line{% endfilename %} C:\Users\Name\djangogirls> myvenv\Scripts\activate + + +> **ПРИМІТКА:** На Windows 10 Ви можете отримати помилку у Windows PowerShell, що повідомить `виконання скриптів на цій системі вимкнено`. У цьому випадку, відкрийте іншу опцію Windows PowerShell "Запуск від імені адміністратора". Потім спробуйте набрати наступну команду перед тим, як започаткувати ваше віртуальне середовище: +> +> {% filename %}command-line{% endfilename %} +> +> C:\WINDOWS\system32> Set-ExecutionPolicy -ExecutionPolicy RemoteSigned +> Execution Policy Change +> The execution policy helps protect you from scripts that you do not trust. Changing the execution policy might expose you to the security risks described in the about_Execution_Policies help topic at http://go.microsoft.com/fwlink/?LinkID=135170. Do you want to change the execution policy? [Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is "N"): A +> + + -#### Linux та OS X +> **NOTE:** For users of the popular editor VS Code, which comes with an integrated terminal based off windows PowerShell, if you wish to stick with the integrated terminal, you may run the following command to activate your virtual environment: +> +> $ . myvenv\Scripts\activate.ps1 +> +> +> Перевага в тому, що вам не потрібно перемикатися між вікнами редактора та вікнами командного рядка. + + + + Запустіть своє віртуальне середовище виконавши: - $ source myvenv/bin/activate +{% filename %}command-line{% endfilename %} -Не забудьте, що замість `myvenv` повинно бути вибране вами ім'я для віртуального середовища! + $ source myvenv/bin/activate + -> __ЗАУВАЖЕННЯ:__ іноді використання `source` може бути недоступно. В цьому випадку спробуйте зробити наступне: +Не забудьте замінити `myvenv` на вибране Вами `віртуальне `ім'я! +> **ПРИМІТКА:** Якщо командне `джерело` не є доступним, спробуйте зробити замість цього це: +> +> {% filename %}command-line{% endfilename %} +> > $ . myvenv/bin/activate +> + + + +Про активізацію віртуального середовища ви дізнаєтесь коли побачите підказку в командному рядку консолі, котра виглядатиме наступним чином. + +When working within a virtual environment, `python` will automatically refer to the correct version so you can use `python` instead of `python3`. + +OK, we have all important dependencies in place. We can finally install Django! + +## Installing Django {#django} + +Now that you have your `virtualenv` started, you can install Django. + +Before we do that, we should make sure we have the latest version of `pip`, the software that we use to install Django: + +{% filename %}command-line{% endfilename %} + + (myvenv) ~$ python -m pip install --upgrade pip + + +### Installing packages with requirements + +A requirements file keeps a list of dependencies to be installed using `pip install`: + +First create a `requirements.txt` file inside of the `djangogirls/` folder, using the code editor that you installed earlier. You do this by opening a new file in the code editor and then saving it as `requirements.txt` in the `djangogirls/` folder. Your directory will look like this: + + djangogirls + ├── myvenv + │ └── ... + └───requirements.txt + + +In your `djangogirls/requirements.txt` file you should add the following text: + +{% filename %}djangogirls/requirements.txt{% endfilename %} + + Django~={{ book.django_version }} + + +Now, run `pip install -r requirements.txt` to install Django. + +{% filename %}command-line{% endfilename %} -Про активацію віртуального середовища ви дізнаєтесь, коли побачите префікс `(myvenv)` в командному рядку консолі + (myvenv) ~$ pip install -r requirements.txt + Collecting Django~={{ book.django_version }} (from -r requirements.txt (line 1)) + Downloading Django-{{ book.django_version }}-py3-none-any.whl (7.9MB) + Installing collected packages: Django + Successfully installed Django-{{ book.django_version }} + -Під час роботи у віртуальному середовищі, `python` буде автоматичному посилатися на правильну версію, отже ви можете використовувати `python` замість `python3`. + -Добре, маємо усі необхідні залежності. Можемо зрештою встановити Django! +> If you get an error when calling pip on Windows, please check if your project pathname contains spaces, accents or special characters (for example, `C:\Users\User Name\djangogirls`). If it does, please consider using another place without spaces, accents or special characters (suggestion: `C:\djangogirls`). Create a new virtualenv in the new directory, then delete the old one and try the above command again. (Moving the virtualenv directory won't work since virtualenv uses absolute paths.) -## Встановлення Django + -Наразі, коли ваш `virtualenv` активований, можна встановлювати Django використавши `pip`. В консолі, запустіть `pip install django==1.11` (зазначте, що тут ми користуємося подвійним знаком рівності: `==`). + - (myvenv) ~$ pip install django==1.11 - Downloading/unpacking django==1.11 - Installing collected packages: django - Successfully installed django - Cleaning up... +> Your command line might freeze when you try to install Django. If this happens, instead of the above command use: +> +> {% filename %}command-line{% endfilename %} +> +> C:\Users\Name\djangogirls> python -m pip install -r requirements.txt +> -для Windows -> Якщо ви отримуєте помилку коли викликаєте pip на Windows, будь ласка, перевірте чи шлях до вашого проекту не містить пробілів, наголосів чи спеціальних символів (наприклад `C:\Users\User Name\djangogirls`). Якщо містить - перемістіть його в місце шлях до якого не містить таких символів (пропонуємо: `C:\djangogirls`). Після переміщення спробуйте запустити вищевказану команду знову. + -для Windows 8 чи Windows 10 -> Ваш командний рядок може зависнути, після того як ви спробуєте встановити Django. Якщо це сталось, замість вище зазначеної команди використовуйте: + -> C:\Users\Name\djangogirls> python -m pip install django==1.11 +> If you get an error when calling pip on Ubuntu 12.04 please run `python -m pip install -U --force-reinstall pip` to fix the pip installation in the virtualenv. -для Linux -> Якщо виникла помилка під час запуску pip на Ubuntu 12.04, будь ласка, запустіть `python -m pip install -U --force-reinstall pip` щоб коректно перевстановити pip у віртуальному середовищі. + -Оце усе! Зараз ви (нарешті) готові створити додаток Django! +That's it! You're now (finally) ready to create a Django application! \ No newline at end of file diff --git a/uk/django_models/README.md b/uk/django_models/README.md old mode 100755 new mode 100644 index 03d73aa8968..a92160f9581 --- a/uk/django_models/README.md +++ b/uk/django_models/README.md @@ -1,16 +1,16 @@ # Django моделі -Наразі ми б хотіли створити щось, що зберігатиме усі дописи в нашому блозі. Але щоб бути спроможними це зробити, нам необхідно трохи поговорити про таке поняття, як об'єкти `objects`. +Наразі ми б хотіли створити щось, що вміє зберігати усі пости в нашому блозі. Але щоб бути спроможними це зробити, нам необхідно трохи поговорити про таке поняття, як `objects` (об'єкти). ## Об'єкти -Існує така концепція в програмуванні, яка називається `Об'єктно-орієнтовне програмування`. Ідея полягає в тому, що замість написання нудної послідовності програмних інструкцій ми можемо моделювати речі і визначати як вони будуть взаємодіяти одна з одною. +Існує така концепція в програмуванні, яка називається `об'єктно-орієнтовне програмування`. Ідея полягає в тому, що замість написання нудної послідовності програмних інструкцій ми можемо моделювати речі і визначати як вони будуть взаємодіяти одна з одною. -Отже, що ж таке об'єкт? Це набір властивостей та дій. Звучить дивно, але представимо приклад. +Отже, що ж таке об'єкт? Це набір властивостей та дій. Звучить дивно, але ми надамо приклад. -Якщо ми хочемо змоделювати кота, то створимо об'єкт `Cat`, що має деякі властивості, наприклад, колір, вік, настрій, власник - `color`, `age`, `mood` (хороший, поганий, сонний ;)), `owner` (це буде об'єкт `Person` або, можливо, у випадку бездомного кота, ця властивість буде пустою). +Якщо ми хочемо змоделювати кота, то створимо об'єкт `Cat`, що має деякі властивості, наприклад, - колір `color`, вік `age`, настрій `mood` (гарний, поганий, сонний ;)), власник `owner` (це буде об'єкт `Person` або, можливо, у випадку бездомного кота, ця властивість може бути пустою). -Далі припустимо, що наш кіт `Cat` має певний набір дій, наприклад, муркотіти, шкрябатися, їсти - `purr`, `scratch`, `feed` (де ми будемо давати коту певний котячий корм `CatFood`, котрий міг би бути окремим об'єктом зі своїми властивостями, наприклад, смак - `taste`). +Кіт `Cat` має певний набір дій, наприклад, муркотіти `purr`, шкрябатися `scratch`, їсти `feed` (де ми будемо давати коту певний котячий корм `CatFood`, котрий міг би бути окремим об'єктом та мати свої властивості, наприклад, смак `taste`). Cat -------- @@ -21,17 +21,18 @@ purr() scratch() feed(cat_food) - + CatFood -------- taste + Отже, основна ідея полягає в тому, щоб описати реальні речі в програмному коді з усіма їх властивостями (так званими властивостями об'єкта `object properties`) і діями (так званими методами `methods`). -Як же ми тоді змоделюємо дописи у блозі? Ми ж хочемо створити блог, правда? +Як же ми тоді змоделюємо пости у блозі? Ми ж хочемо створити блог, правда? -Нам треба відповісти на питання: що таке допис у блозі? Які властивості він повинен мати? +Нам треба відповісти на питання: що таке пост у блозі? Які властивості він повинен мати? Однозначно наш допис повинен містити певний текст із змістом і заголовком, правда ж? Було б також непогано знати хто його написав, отже нам потрібен автор. Зрештою, ми б хотіли знати коли було створено і опубліковано цей допис. @@ -42,49 +43,68 @@ author created_date published_date + -Якого роду дії можна було б вчиняти з дописом у блозі? Було б непогано мати певний метод, що публікує допис, правда ж? +Якого роду дії можна було б вчиняти з постом у блозі? Було б непогано мати певний метод, що публікує пост, правда ж? Отже, нам потрібен метод `publish`. -Таким чином, знаючи, чого ми хочемо досягти, можемо почати моделювати це в Django! +Таким чином, знаючи нарешті, чого ми хочемо досягти, можемо почати моделювати це в Django! ## Django модель -Знаючи яким є наш об'єкт, можемо створити Django модель для допису у нашому блозі. +Знаючи яким є наш об'єкт, можемо створити Django модель для постів у нашому блозі. -Модель в Django - це спеціальний вид об'єкту, який зберігається в базі даних. База даних є набором певних даних. Це є місце, де ви будете зберігати інформацію про користувачів, дописи у вашому блозі тощо. Надалі для зберігання наших даних будемо використовувати базу даних SQLite. Це база даних, що встановлена в Django за замовчуванням і, цього буде наразі для нас достатньо. +Модель в Django - це спеціальний вид об'єкту, який зберігається в базі даних. База даних є набором певних даних. Це є місце, де ви будете зберігати інформацію про користувачів, дописи у вашому блозі тощо. Надалі для зберігання наших даних будемо використовувати базу даних SQLite. Це база даних, що встановлена в Django за замовчуванням і, цього буде наразі для нас достатньо. -Ви можете уявляти модель в базі даних як таблицю зі стовпчиками (полями) та рядками (дані). +Ви можете уявляти модель в базі даних як таблицю зі стовпчиками (полями) та рядками (дані). ### Створення додатку Щоб підтримувати все у порядку, створимо окремий додаток всередині нашого проекту. Дуже добре зберігати в усьому організованість з самого початку. Щоб створити додаток треба запустити наступну команду в консолі (з директорії `djangogirls`, де знаходиться файл `manage.py`): +{% filename %}Mac OS X або Linux:{% endfilename %} + (myvenv) ~/djangogirls$ python manage.py startapp blog + + +{% filename %}Windows:{% endfilename %} -Ви побачите, що створено нову директорію `blog`, яка містить певну кількість файлів. Директорії та файли в нашому проекті мають виглядати наступним чином: + (myvenv) C:\Users\Name\djangogirls> python manage.py startapp blog + + +Ви побачите, що була створена нова директорія `blog`, яка містить певну кількість файлів. Директорії та файли в нашому проекті мають виглядати наступним чином: djangogirls - ├── mysite - | __init__.py - | settings.py - | urls.py - | wsgi.py + ├── blog + │   ├── admin.py + │   ├── apps.py + │   ├── __init__.py + │   ├── migrations + │   │   └── __init__.py + │   ├── models.py + │   ├── tests.py + │   └── views.py + ├── db.sqlite3 ├── manage.py - └── blog - ├── migrations - | __init__.py - ├── __init__.py - ├── admin.py - ├── models.py - ├── tests.py - └── views.py + ├── mysite + │   ├── asgi.py + │   ├── __init__.py + │   ├── settings.py + │   ├── urls.py + │   └── wsgi.py + ├── myvenv + │   └── ... + └── requirements.txt + + -Після створення ми також повинні повідомити Django, що він має використовувати цей додаток. Ми робимо це у файлі `mysite/settings.py`. Нам треба знайти `INSTALLED_APPS` та додати рядок `'blog',` зверху над `)`. Таким чином, остаточний результат повинен мати наступний вигляд: +Після створення застосунку, ми також повинні повідомити Django, що він має використовувати його. Ми робимо це у файлі `mysite/settings.py` - відкрийте його в редакторі коду. We need to find `INSTALLED_APPS` and add a line containing `'blog',` just above `]`. Таким чином, остаточний результат повинен мати наступний вигляд: + +{% filename %}mysite/settings.py{% endfilename %} ```python -INSTALLED_APPS = ( +INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', @@ -92,14 +112,16 @@ INSTALLED_APPS = ( 'django.contrib.messages', 'django.contrib.staticfiles', 'blog', -) +] ``` -### Створення моделі допису у блозі +### Створення моделі поста у блозі + +У файлі `blog/models.py` ми визначаємо всі об'єкти, що називаються моделями - `Models`. Це і є місце, де ми будемо визначати наш пост. -У файлі `blog/models.py` ми визначаємо всі об'єкти, що називаються моделі - `Models`. Це і є місце, де ми будемо визначати наш допис. +Відкриємо `blog/models.py` в редакторі коду, видалім усе з нього, і запишемо наступний код: -Відкриємо `blog/models.py`, видалимо все звідси та запишемо наступний код: +{% filename %}blog/models.py{% endfilename %} ```python from django.conf import settings @@ -111,10 +133,8 @@ class Post(models.Model): author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) title = models.CharField(max_length=200) text = models.TextField() - created_date = models.DateTimeField( - default=timezone.now) - published_date = models.DateTimeField( - blank=True, null=True) + created_date = models.DateTimeField(default=timezone.now) + published_date = models.DateTimeField(blank=True, null=True) def publish(self): self.published_date = timezone.now() @@ -124,49 +144,59 @@ class Post(models.Model): return self.title ``` -> Двічі перевірте, чи ви використали два знаки підкреслення (`_`) з кожної сторони `str`. Ця домовленість часто використовується в Python й іноді ми називаємо її "dunder" (скорочення від англ. "double-underscore"). +> Переконайтесь, що ви використовуєте два символи підкреслення (`_`) з кожного боку `str`. Ця домовленість часто використовується в Python й іноді ми називаємо її "dunder" (скорочення від англ. "double-underscore"). Страхіття якесь, правда ж? Але не хвилюйтесь, ми пояснимо, що означають ці рядки! -Усі лінії, що починаються з `from` або `import` - це лінії, які додають деякі біти з інших файлів. Отже замість того, щоб копіювати і вставляти одне й те ж в кожному файлі,ми можемо включити деякі частини з `from ... import ...`. +Усі рядки, що починаються з `from` або `import` - це рядки, які додають деяку інформацію з інших файлів. Отже замість того, щоб копіювати і вставляти одне й те ж в кожному файлі,ми можемо включити деякі частини з `from ... import ...`. -`class Post(models.Model):` - цей рядок визначає нашу модель (це об'єкт `object`). +`class Post(models.Model):` – цей рядок визначає нашу модуль( це об'єкт `object`). - `class` - це спеціальне ключове слово, яке показує що ми визначаємо об'єкт. -- `Post` - це ім'я нашої моделі. Ми можемо давати їй різні імена (але ми повинні уникати використання спеціальних символів та пробілів). Завжди починайте ім'я класу із великої літери. -- `models.Model` означає, що Post є Django моделлю, отже Django знає, що вона повинна бути збережена у базі даних. +- `Post` - це ім'я нашої моделі. Ми можемо дати інше ім'я (але ми повинні уникати використання спеціальних символів та пробілів). Завжди починайте ім'я класу із великої літери. +- `models.Model` означає, що Post це Django модель, отже Django знає, що вона повинна бути збережена у базі даних. + +А зараз визначимо властивості, про які ми говорили перед цим: заголовок `title`, текст `text`, дата створення `created_date`, дата публікації `published_date` і автор `author`. Щоб це зробити нам необхідно визначити тип поля (Чи це текст? Число? Дата? Зв'язок із іншим об'єктом, наприклад, об'єктом користувача - User?). -А зараз визначимо властивості, про які ми говорили перед цим: `title`, `text`, `created_date`, `published_date` і `author`. Щоб це зробити нам необхідно визначити тип поля (чи це текст? Число? Дата? Зв'язок із іншим об'єктом, наприклад, об'єкт користувач - User?). +- `models.CharField` - це спосіб визначення тексту з обмеженою кількістю символів. +- `models.TextField` - великі блоки тексту без обмеження по розміру. Ідеально підходить для запису блогу, правильно? +- `models.DateTimeField` - це для дати та часу. +- `models.ForeignKey` - це посилання на іншу модель. -- `models.CharField` - для текстових полів з обмеженням кількісті символів. -- `models.TextField` - великі блоки тексту без обмежень. Ідеально підходить для запису блогу, правильно? -- `models.DateTimeField` - дата та час. -- `models.ForeignKey` - зв'язок із іншою моделлю. +Не будемо пояснювати увесь код, оскільки це може зайняти надто багато часу. You should take a look at Django's documentation if you want to know more about Model fields and how to define things other than those described above (https://docs.djangoproject.com/en/3.2/ref/models/fields/#field-types). -Не будемо пояснювати кожне слово в коді, оскільки це може зайняти надто багато часу. Якщо хочете дізнатися більше про поля моделей, а також як визначати речі відмінні від вище описаних, то дивіться документацію Django (https://docs.djangoproject.com/en/1.11/ref/models/fields/#field-types). +А як щодо `def publish(self):`? Це і є наш метод `publish`, про який ми говорили раніше. `def` означає, що це функція/метод, а `publish` - ім'я методу. Ви можете змінити ім'я методу, якщо захочете. Правило іменування: треба використовувати рядкові букви, а пробіли замінювати нижніми підкресленнями. Наприклад, метод для розрахунку середньої ціни може бути названий `calculate_average_price`. -А як щодо `def publish(self):`? Це і є наш метод `publish`, про який ми говорили раніше. `def` означає, що це функція/метод, а `publish` - ім'я методу. Ви можете змінити ім'я методу, якщо захочете. Правило іменування: треба використовувати рядкові букви, а пробіли замінювати підкресленнями. Наприклад, метод для розрахунку середньої ціни може бути названий `calculate_average_price`. +Методи часто `return` (повертають) щось. Приклад цього можна побачити в методі `__str__`. У цьому сценарії, коли ми викликаємо `__str__()`, то отримуємо текст (**string**) із заголовком посту. -Методи часто повертають (`return`) щось. Приклад цього можна побачити в методі `__str__`. У цьому сценарії, коли ми викликаємо `__str__()`, то отримуємо текст (**string**) із заголовком посту. +Також зверніть увагу, що обидва метода `def publish(self):` і `def __str__(self):` відносяться до одного класу. Оскільки Python чутливий до пробілів, нам потрібно контролювати відступ наших методів всередині класу. В іншому випадку методи не будуть належати до класу, і ви можете отримати непередбачувану поведінку. Якщо вам щось незрозуміло з приводу моделей, не соромтеся запитувати у вашого тренера! Ми знаємо, що це дуже складно, особливо коли ви одночасно вивчаєте об'єкти і функції. Але сподіваємося наразі це виглядає трохи менш таємничим для вас! ### Створення таблиць для моделей в базі даних -Останній крок - додати нашу нову модель до нашої бази даних. Спочатку потрібно повідомити Django, що змінилась наша модель (ми щойно створили її!). Наберіть `python manage.py makemigrations blog`. Це буде виглядати так: +Останній крок - додати нашу нову модель до нашої бази даних. Спочатку потрібно повідомити Django, що змінилась наша модель (Ми щойно створили її!) Перейдіть до вашої консолі і наберіть `python manage.py makemigrations blog`. Це буде виглядати так: + +{% filename %}command-line{% endfilename %} (myvenv) ~/djangogirls$ python manage.py makemigrations blog Migrations for 'blog': - 0001_initial.py: - - Create model Post + blog/migrations/0001_initial.py + + - Create model Post + + +**Примітка:** Не забудьте зберегати змінені файли. В іншому випадку ваш комп'ютер виконуватиме попередню версію, що може призвести до неочікуваних повідомлень про помилки. + +Django підготував для нас файл з міграцією, який ми повинні тепер застосувати до нашої бази даних. Наберіть `python manage.py migrate blog`, на виході отримаємо: -Django підготував для нас файл перенесення, який ми повинні тепер застосувати до нашої бази даних. Наберіть `python manage.py migrate blog`, на виході отримаємо: +{% filename %}command-line{% endfilename %} (myvenv) ~/djangogirls$ python manage.py migrate blog Operations to perform: Apply all migrations: blog Running migrations: - Rendering model states... DONE Applying blog.0001_initial... OK + -Ура! Наша модель допису Post тепер знаходиться у нашій базі даних. Було б добре побачити її, правда ж? Для цього перейдемо до наступного розділу! +Ура! Наша модель допису Post тепер знаходиться у нашій базі даних. Було б добре побачити її, правда ж? Для цього перейдемо до наступного розділу! \ No newline at end of file diff --git a/uk/django_orm/README.md b/uk/django_orm/README.md old mode 100755 new mode 100644 index 611ca099a54..52140218887 --- a/uk/django_orm/README.md +++ b/uk/django_orm/README.md @@ -1,145 +1,221 @@ # Django ORM і QuerySets -У цьому розділі ви дізнаєтесь, як Django з'єднується із базою даних і зберігає в ній дані. Почнемо занурення! - +У цьому розділі ви дізнаєтесь як Django з'єднується із базою даних і зберігає в ній дані. Почнемо занурення! ## Що таке QuerySet? -A QuerySet є, по суті, списком об'єктів заданої моделі Model. QuerySet дозволяє вам считувати дані з бази даних, а також фільтрувати і впорядковувати їх. +A QuerySet is, in essence, a list of objects of a given Model. QuerySets allow you to read the data from the database, filter it and order it. Найпростіше показати на прикладі. Давайте спробуємо? - ## Django shell Відкрийте свій локальний термінал (не PythonAnywhere) і наберіть цю команду: +{% filename %}command-line{% endfilename %} + (myvenv) ~/djangogirls$ python manage.py shell + -Результатом повинно бути: +Результат повинен бути наступним: - (InteractiveConsole) - >>> +{% filename %}command-line{% endfilename %} -Ви опинетесь в інтерактивній консолі Django. Це щось подібне на командний рядок Python, але має додаткову магію Django :). Звичайно, тут ви також можете використовувати усі команди Python. +```python +(InteractiveConsole) +>>> +``` +You're now in Django's interactive console. It's just like the Python prompt, but with some additional Django magic. :) You can use all the Python commands here too. ### Усі об'єкти Давайте спробуємо спочатку вивести усі наші пости. Можна це зробити за допомогою наступної команди: - >>> Post.objects.all() - Traceback (most recent call last): - File "", line 1, in - NameError: name 'Post' is not defined +{% filename %}command-line{% endfilename %} -Ой! З'явилась помилка. Вона повідомляє нам, що немає ніяких постів. І це правильно, адже ми забули спочатку імпортувати їх! +```python +>>> Post.objects.all() +Traceback (most recent call last): + File "", line 1, in +NameError: name 'Post' is not defined +``` - >>> from blog.models import Post +Oops! An error showed up. It tells us that there is no Post. It's correct – we forgot to import it first! -Усе просто: імпортуємо модель `Post` з `blog.models`. Спробуємо вивести усі пости знову: +{% filename %}command-line{% endfilename %} - >>> Post.objects.all() - , ]> +```python +>>> from blog.models import Post +``` -Це список з дописів, з якими ми працювали раніше! Ми створили ці дописи через панель адміністратора Django. Проте, зараз ми хочемо створити нові дописи за допомогою Python, як ми цього доб'ємось? +We import the model `Post` from `blog.models`. Let's try displaying all posts again: +{% filename %}command-line{% endfilename %} + +```python +>>> Post.objects.all() +, ]> +``` + +This is a list of the posts we created earlier! We created these posts using the Django admin interface. But now we want to create new posts using Python, so how do we do that? ### Створення об'єкту Мова йдеться про те, як створити об'єкт Post в базі даних: - >>> Post.objects.create(author=me, title='Sample title', text='Test') +{% filename %}command-line{% endfilename %} + +```python +>>> Post.objects.create(author=me, title='Sample title', text='Test') +``` -Однак, ми пропустили один елемент : `me`. Потрібно передати екземпляр моделі `User` у якості автора. Як це зробити? +But we have one missing ingredient here: `me`. We need to pass an instance of `User` model as an author. How do we do that? Спочатку імпортуємо модель User: - >>> from django.contrib.auth.models import User +{% filename %}command-line{% endfilename %} + +```python +>>> from django.contrib.auth.models import User +``` Які користувачі присутні в нашій базі даних? Спробуймо це: - >>> User.objects.all() - ]> +{% filename %}command-line{% endfilename %} + +```python +>>> User.objects.all() +]> +``` + +This is the superuser we created earlier! Let's get an instance of the user now (adjust this line to use your own username): -Це суперкористувач, якого ми створили раніше! Нам потрібен його екземпляр: +{% filename %}command-line{% endfilename %} - me = User.objects.get(username='ola') +```python +>>> me = User.objects.get(username='ola') +``` -Як бачимо, ми отримали користувача із іменем, що дорівнює 'ola'. Чудово! Звісно, ви мали б використовувати ваше ім'я. +As you can see, we now `get` a `User` with a `username` that equals 'ola'. Neat! Тепер ми нарешті можемо створити наш пост: - >>> Post.objects.create(author=me, title='Sample title', text='Test') +{% filename %}command-line{% endfilename %} -Ура! Бажаєте перевірити, чи це працює? +```python +>>> Post.objects.create(author=me, title='Sample title', text='Test') + +``` - >>> Post.objects.all() - , , ]> +Ура! Бажаєте перевірити чи це працює? -Є, ще один допис в списку! +{% filename %}command-line{% endfilename %} +```python +>>> Post.objects.all() +, , ]> +``` -### Додайте більше постів +Є, ще один допис в списку! -А тепер можете трохи побавитися і пододавати більше постів, щоб побачити, як це працює. Додайте ще 2-3 поста і переходьте до наступної частини. +### Додайте більше постів +You can now have a little fun and add more posts to see how it works. Add two or three more and then go ahead to the next part. ### Фільтрування об'єктів -Великою частиною QuerySets є можливість фільтрувати запити до бази даних. Скажімо, ми хочемо відшукати усі пости, що мають автора ola. Будемо використовувати `filter` замість `all` в `Post.objects.all()`. В дужках ми вказуємо яким умовам повинен відповідати пост, щоб завершити наш запит до бази даних. У нашому випадку це автор `author`, що дорівнює `me`. В Django цю умову можна виразити як: `author=me`. Тепер наш шматок коду виглядає так: +A big part of QuerySets is the ability to filter them. Let's say we want to find all posts that user ola authored. Будемо використовувати `filter` замість `all` в `Post.objects.all()`. In parentheses we state what condition(s) a blog post needs to meet to end up in our queryset. In our case, the condition is that `author` should be equal to `me`. The way to write it in Django is `author=me`. Тепер наш шматок коду виглядає так: + +{% filename %}command-line{% endfilename %} + +```python +>>> Post.objects.filter(author=me) +, , , ]> +``` + +Or maybe we want to see all the posts that contain the word 'title' in the `title` field? - >>> Post.objects.filter(author=me) - , , , ]> +{% filename %}command-line{% endfilename %} -Чи, можливо, ми хочемо побачити усі пости, що містять слово 'title' в полі `title`? +```python +>>> Post.objects.filter(title__contains='title') +, ]> +``` - >>> Post.objects.filter(title__contains='title') - , ]> +> **Зауваження** Тут використано два знаки підкреслювання (`_`) між `title` і `contains`. Django's ORM uses this rule to separate field names ("title") and operations or filters ("contains"). If you use only one underscore, you'll get an error like "FieldError: Cannot resolve keyword title_contains". -> **Зауваження** Тут використано два знаки підкреслювання (`_`) між `title` і `contains`. Django ORM використовує цей синтаксис щоб відокремити імена полів ("title") і операції або фільтри ("contains"). Якщо ви раптом використаєте одне підкреслювання, то отримаєте помилку на кшталт "FieldError: Cannot resolve keyword title_contains". +You can also get a list of all published posts. We do this by filtering all the posts that have `published_date` set in the past: -Ви також можете отримати список всіх опублікованих дописів. Ми робимо це шляхом фільтрації всіх дописів, які мають встановлене поле `published_date`: - >>> from django.utils import timezone - >>> Post.objects.filter(published_date__lte=timezone.now()) - [] +{% filename %}command-line{% endfilename %} -На жаль, доданий з Python консолі допис ще не опублікований. Ми можемо змінити це! Спершу отримаємо екземпляр допису, який хочемо опублікувати: +```python +>>> from django.utils import timezone +>>> Post.objects.filter(published_date__lte=timezone.now()) + +``` - >>> post = Post.objects.get(title="Sample title") +Unfortunately, the post we added from the Python console is not published yet. But we can change that! First get an instance of a post we want to publish: -А далі опублікуємо його за допомогою нашого методу `publish`! +{% filename %}command-line{% endfilename %} - >>> post.publish() +```python +>>> post = Post.objects.get(title="Sample title") +``` -Тепер спробуйте отримати список опублікованих дописів знову (натисніть стрілку вгору 3 рази, а потім `enter`): +А далі опублікуємо його за допомогою нашого методу `publish`: - >>> Post.objects.filter(published_date__lte=timezone.now()) - ]> +{% filename %}command-line{% endfilename %} +```python +>>> post.publish() +``` + +Now try to get list of published posts again (press the up arrow key three times and hit `enter`): + +{% filename %}command-line{% endfilename %} + +```python +>>> Post.objects.filter(published_date__lte=timezone.now()) +]> +``` ### Впорядкування об'єктів QuerySets також дозволяє впорядковувати список об'єктів. Давайте спробуємо впорядкувати їх за параметром поля `created_date`: - >>> Post.objects.order_by('created_date') - , , , ]> +{% filename %}command-line{% endfilename %} -Також можна здійснити впорядкування у зворотньому напрямку, додавши `-` на початку: +```python +>>> Post.objects.order_by('created_date') +, , , ]> +``` - >>> Post.objects.order_by('-created_date') - , , , ]> +Також можна здійснити впорядкування у зворотньому напрямку додавши `-` на початку: +{% filename %}command-line{% endfilename %} -### З'єднання QuerySets +```python +>>> Post.objects.order_by('-created_date') +, , , ]> +``` -QuerySets можна поєднувати, створюючи **ланцюжки**: +### Complex queries through method-chaining - >>> Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date') +As you saw, some methods on `Post.objects` return a QuerySet. The same methods can in turn also be called on a QuerySet, and will then return a new QuerySet. Thus, you can combine their effect by **chaining** them together: + +```python +>>> Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date') +, , , ]> +``` Це дуже потужний механізм, що дозволяє вам писати дуже складні запити. Клас! Тепер ви готові до наступної частини! Щоб закрити командну оболонку, наберіть: - >>> exit() - $ +{% filename %}command-line{% endfilename %} + +```python +>>> exit() +$ +``` \ No newline at end of file diff --git a/uk/django_start_project/README.md b/uk/django_start_project/README.md old mode 100755 new mode 100644 index 8b121540a53..69867a1e522 --- a/uk/django_start_project/README.md +++ b/uk/django_start_project/README.md @@ -1,47 +1,65 @@ # Ваш перший Django проект! -> Частина цього розділу базується на матеріалах Geek Girls Carrots (https://github.com/ggcarrots/django-carrots). +> Part of this chapter is based on tutorials by Geek Girls Carrots (https://github.com/ggcarrots/django-carrots). +> +> Частини цієї глави засновані на [jango-marcador tutorial](http://django-marcador.keimlink.de/), який є дозволеним міжнародною ліцензією ShareAlike 4.0 від Creative Commons Attributes. Авторське право на навчальні матеріали django-marcador tutorial належить Markus Zapke-Gründemann та ін. -> Частина цього розділу базується на матеріалх [django-marcador tutorial](http://django-marcador.keimlink.de/) -ліцензованих Creative Commons Attribution-ShareAlike 4.0 International License. -Авторське право на навчальні матеріали django-marcador tutorial належить -Markus Zapke-Gründemann та ін. - -Ми збираємося створити простий блог! +We're going to create a small blog! Перший крок - це почати новий проект Django. По суті, це означає що ми запустимо деякі скрипти, які надає Django, що створять для нас скелет Django проекту. Це просто кілька каталогів та файлів, якими ми користуватимемось пізніше. Імена деяких файлів і папок є дуже важливими для Django. Не можна перейменовувати файли, які ми зараз будемо створювати. Їх переміщення в різні місця також не є хорошою ідеєю. Для того щоб Django міг знаходити важливі речі, потрібно підтримувати задану архітектуру. -> Пам'ятайте, що усе треба запускати у віртуальному середовищі. Якщо ви не бачите префікс `(myvenv)` в консолі, то потрібно активувати ваше віртуальне середовище. Ми пояснювали як це зробити у розділі __Встановлення Django__ в частині __Робота з віртуальним середовищем__. -Команда `myvenv\Scripts\activate` на Windows або `source myvenv/bin/activate` на Mac OS / Linux зробить це за вас. +> Пам'ятайте, що усе треба запускати у віртуальному середовищі. Якщо ви не бачите префікс `(myvenv)` в консолі, то потрібно активувати ваше віртуальне середовище. Ми пояснювали як це зробити у розділі **Встановлення Django** в частині **Робота з віртуальним середовищем**. Набираючи `myvenv\Scripts\activate` на Windows чи `source myvenv/bin/activate` на Mac OS X або Linux зробить це для Вас. + + + +На Вашій Mac OS X чи Linux консолі, Ви повинні виконати наступну команду.**Не забувайте додати крапку`.`в кінці!** -В терміналі Mac OS або Linux слід запустити наступну команду; **не забудьте додати крапку `.` в кінці**: +{% filename %}command-line{% endfilename %} (myvenv) ~/djangogirls$ django-admin startproject mysite . + -У Windows; **не забудьте додати крапку `.` в кінці**: +> Крапка `.` має вирішальне значення, оскільки вона означає "встанови Django в поточний каталог" (символ крапки `.` використовується щоб не писати повний шлях). +> +> **Примітка**Набираючи вище зазначену команду, пам'ятайте, що Ви набираєте тільки частину, яка починається з `django-admin`. Частина `(myvenv) ~/djangogirls$`, показана тут, є лише прикладом підказки, яка запропонує ввести дані у Вашому командному рядку. - (myvenv) C:\Users\Name\djangogirls> django-admin startproject mysite . + -> Крапка `.` має ключове значення, оскільки вона означає "встанови Django в поточний каталог" (символ крапки `.` використовується, щоб не писати повний шлях) + -> **Примітка** Коли набираете команду вище, пам'ятайте, що потрібно друкувати тільки ту частину, яка починається з `django-admin` або `django-admin.py`. -Частини шляху `~/djangogirls$ (myvenv)` та `(myvenv) C:\Users\Name\djangogirls >`вказані тут лише -як приклад запрошення командного рядка до введення команд. +На Windows Ви повинні виконати наступну команду. **(Не забувайте додавати крапку`. в кінці):

-`django-admin.py` - це скрипт, що створить для вас усі необхідні папки і файли. Наразі ви повинні мати структуру, котра виглядає наступним чином: +

{% filename %}command-line{% endfilename %}

- djangogirls - ├───manage.py - └───mysite - settings.py - urls.py - wsgi.py - __init__.py +
(myvenv) C:\Users\Name\djangogirls> django-admin.exe startproject mysite .
+`
+> Крапка `.` має вирішальне значення, оскільки вона означає "встанови Django в поточний каталог" (символ крапки `.` використовується щоб не писати повний шлях). +> +> **Примітка**Набираючи вище зазначену команду, пам'ятайте, що Ви набираєте тільки частину, яка починається з `django-admin.exe`. Частина `(myvenv) C:\Users\Name\djangogirls>`, показана тут, є лише прикладом підказки, яка запропонує ввести дані у Вашому командному рядку. -`manage.py` - скрипт, що допомагає керувати сайтом. З його допомогою ми зможемо запускати веб сервер без встановлення чогось іще додатково, серед іншого. + + +`django-admin.py` - це скрипт, що створить для вас усі необхідні папки і файли. Наразі ви повинні мати структуру, котра виглядає наступним чином: + + djangogirls + ├── manage.py + ├── mysite + │   ├── asgi.py + │   ├── __init__.py + │   ├── settings.py + │   ├── urls.py + │   └── wsgi.py + ├── myvenv + │   └── ... + └── requirements.txt + + +> **Примітка**: у Вашій структурі каталогів, Ви також побачите Ваш `myvenv` каталог, який ми створили раніше. + +`manage.py` - це скрипт, який допомагає з управлінням сайтом. Завдяки йому ми зможемо (серед іншого) запустити вебсервер на Вашому комп'ютері без установки чого-небудь ще. Файл `settings.py` містить конфігурацію вашого веб сайту. @@ -49,87 +67,201 @@ Markus Zapke-Gründemann та ін. Проігноруємо поки інші файли, адже ми не будемо їх змінювати. Єдина річ, яку варто пам'ятати - не видалити їх ненароком! - ## Зміна налаштувань Здійснимо деякі зміни в `mysite/settings.py`. Відкриємо файл в текстовому редакторі, який ви мали встановити раніше. -Було б непогано мати коректний час на нашому сайті. Перейдіть до [списку часових поясів на Вікіпедії](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) та скопіюйте відповідний часовий пояс (TZ). (напр. `Europe/Kiev`) +**Примітка**: Майте на увазі, що `settings.py` є звичайним файлом, як і будь-який інший. Ви можете відкрити його зсередини кодового редактору, використовуючи меню "file -> open". Це дозволить Вам відкрити звичайне вікно, в якому Ви зможете перейти до Вашого `settings.py` файлу та вибрати його. Крім того, Ви можете відкрити файл, якщо перейдете в папку the djangogirls на Вашому робочому столі, натискаючи на неї правою кнопкою миші. Після цього виберіть Ваш редактор коду зі списку. Вибір редактора є важливим через те, що у вас можуть бути встановлені інші програми, які можуть відкрити файл, але не дозволять вам його редагувати. -У файлі settings.py знайдіть рядок, що містить `TIME_ZONE` і замініть його на ваш часовий пояс: +Було б непогано мати коректний час на нашому сайті. Перейдіть в [Wikipedia's list of time zones](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) і скопіюйте відповідний часовий пояс (TZ) (e.g. `Europe/Berlin`). + +У файлі `settings.py`, знайдіть рядок, що містить `TIME_ZONE` і змініть його, щоб вибрати Ваш часовий пояс. Наприклад: + +{% filename %}mysite/settings.py{% endfilename %} ```python -TIME_ZONE = 'Europe/Kiev' +TIME_ZONE = 'Europe/Berlin' ``` -Попередній рядок показує як обрати часовий пояс "Europe/Kiev" +Мовний код складається з мови, наприклад: `en` для англійців або `de` для німців, і код країни, наприклад: `de` для Німеччини або `ch` для Швейцарії. Якщо англійська не є Вашою рідною мовою, Ви можете додати це, щоб змінити кнопки за замовчуванням і сповіщення від Django відповідно до Вашої мови. Таким чином, у вас буде кнопка "Скасувати", перекладена на мову, яку ви визначили тут. До [Django додається велика кількість підготовлених перекладів](https://docs.djangoproject.com/en/3.2/ref/settings/#language-code). + +Якщо Вам потрібна інша мова, змініть мовний код, змінивши наступний рядок: + +{% filename %}mysite/settings.py{% endfilename %} + +```python +LANGUAGE_CODE = 'de-ch' +``` +Нам також потрібно буде додати шлях для статичних файлів. (Ми дізнаємося все про статичні файли та CSS пізніше в цьому уроці.) Опустіться до *кінця* файлу, і просто під вхід `STATIC_URL`, додайте новий під назвою `STATIC_ROOT`: -Нам також необхідно додати шлях для статичних файлів (згодом із посібника ви дізнаетесь все про "статичні файли" та листи стилів (CSS)). Перейдіть *в кінець* файлу та додайте новий запис `STATIC_ROOT` одразу під словом `STATIC_URL`: +{% filename %}mysite/settings.py{% endfilename %} ```python STATIC_URL = '/static/' -STATIC_ROOT = os.path.join(BASE_DIR, 'static') +STATIC_ROOT = BASE_DIR / 'static' ``` +Коли `DEBUG` є `True` і `ALLOWED_HOSTS` порожній, хост перевіряється на відповідність `['localhost', '127.0.0.1', '[::1]']`. Це не буде відповідати вашому імені хоста в PythonAnywhere, при розгортанні нашого додатку, тому ми змінимо наступні налаштування: + +{% filename %}mysite/settings.py{% endfilename %} -## Налаштування бази даних +```python +ALLOWED_HOSTS = ['127.0.0.1', '.pythonanywhere.com'] +``` + +> **Примітка**: Якщо ви використовуєте Chromebook, додайте цей рядок у нижній частині вашого settings.py файл: `MESSAGE_STORAGE = 'django.contrib.messages.storage.session.SessionStorage'` +> +> Також додайте`.amazonaws.com` до `ALLOWED_HOSTS`, якщо Ви використовуєте cloud9 +> +> Якщо Ви розміщуєте Ваш проєкт на `Glitch.com`, дозвольте нам захистити секретний ключ the Django, який має залишатися конфіденційним (в іншому випадку, будь-хто, ремікшуючий Ваш проєкт, зможе його побачити): +> +> - Спочатку ми створимо випадковий секретний ключ. Відкрийте термінал Glitch знову і наберіть наступну команду: +> +> {% filename %}command-line{% endfilename %} +> +> ```bash +> python -c 'from django.core.management.utils import get_random_secret_key; \ +> print(get_random_secret_key())' +> ``` +> +> Це має зобразити довгу випадкову стрічку, ідеальну для використання, як секретний ключ для Вашого нового сайту Django. Тепер ми вставимо цей ключ у файл `.env`, котрий Glitch покаже Вам, тільки якщо Ви є власником вебсайту. +> +> - Створіть файл `.env` у корені вашого проєкту і додайте до нього наступну властивість: +> +> {% filename %}.env{% endfilename %} +> +> ```bash +> # Тут, всередині одинарних лапок, ви можете вирізати та вставити випадковий ключ, згенерований вище +> SECRET='3!0k#7ds5mp^-x$lqs2%le6v97h#@xopab&oj5y7d=hxe511jl' +> +> ``` +> +> - Потім оновіть файл параметрів Django, щоб ввести це секретне значення та встановити назву вебсайту Django: +> +> {% filename %}mysite/settings.py{% endfilename %} +> +> ```python +> import os +> +> SECRET_KEY = os.getenv('SECRET') +> ``` +> +> - І трохи далі в тому ж файлі ми вводимо назву вашого нового вебсайту Glitch: +> +> {% filename %}mysite/settings.py{% endfilename %} +> +> ```python +> ALLOWED_HOSTS = [os.getenv('PROJECT_DOMAIN') + ".glitch.me"] +> ``` +> +> Значення `PROJECT_DOMAIN` автоматично генерується Glitch. Це буде відповідати назві Вашого проєкту. + +## Створення бази даних Існує безліч різноманітних програмних продуктів, що працюють із базами даних і можуть зберігати дані для вашого сайту. Ми будемо користуватися таким, що вказаний за замовчуванням - `sqlite3`. Відповідні налаштування вже прописані у файлі `mysite/settings.py`: +{% filename %}mysite/settings.py{% endfilename %} + ```python DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', - 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), + 'NAME': BASE_DIR / 'db.sqlite3', } } ``` Щоб створити базу даних для нашого блогу, давайте запустимо наступне в консолі: `python manage.py migrate` (ми повинні знаходитися всередині директорії `djangogirls`, яка містить файл `manage.py`). Якщо все пройшло успішно, ви маєте побачити щось на кшталт: +{% filename %}command-line{% endfilename %} + (myvenv) ~/djangogirls$ python manage.py migrate Operations to perform: - Synchronize unmigrated apps: messages, staticfiles - Apply all migrations: contenttypes, sessions, admin, auth - Synchronizing apps without migrations: - Creating tables... - Running deferred SQL... - Installing custom SQL... + Apply all migrations: admin, auth, contenttypes, sessions Running migrations: - Rendering model states... DONE Applying contenttypes.0001_initial... OK Applying auth.0001_initial... OK Applying admin.0001_initial... OK + Applying admin.0002_logentry_remove_auto_add... OK + Applying admin.0003_logentry_add_action_flag_choices... OK Applying contenttypes.0002_remove_content_type_name... OK Applying auth.0002_alter_permission_name_max_length... OK Applying auth.0003_alter_user_email_max_length... OK Applying auth.0004_alter_user_username_opts... OK Applying auth.0005_alter_user_last_login_null... OK Applying auth.0006_require_contenttypes_0002... OK + Applying auth.0007_alter_validators_add_error_messages... OK + Applying auth.0008_alter_user_username_max_length... OK + Applying auth.0009_alter_user_last_name_max_length... OK + Applying auth.0010_alter_group_name_max_length... OK + Applying auth.0011_update_proxy_permissions... OK + Applying auth.0012_alter_user_first_name_max_length... OK Applying sessions.0001_initial... OK + Ми це зробили! Час запустити веб сервер і перевірити чи працює наш сайт! +## Запуск вебсервера + Ви повинні знаходитися в папці, що містить файл `manage.py` (папка `djangogirls`). В консолі ми можемо активувати веб сервер запустивши `python manage.py runserver`: +{% filename %}command-line{% endfilename %} + (myvenv) ~/djangogirls$ python manage.py runserver + + +Якщо Ви у Chromebook, скористайтеся краще цією командою: + +{% filename %}Cloud 9{% endfilename %} + + (myvenv) ~/djangogirls$ python manage.py runserver 0.0.0.0:8080 + + +Або цією, якщо Ви використовуєте Glitch: + +{% filename %}Glitch.com terminal{% endfilename %} -Якщо ви використовуєте Windows і бачите помилку `UnicodeDecodeError` слід виконати наступну команду: + $ refresh + + + +Якщо Ви використовуєте Windows і бачите помилку `UnicodeDecodeError`, слід виконати наступну команду: + +{% filename %}command-line{% endfilename %} (myvenv) ~/djangogirls$ python manage.py runserver 0:8000 + +А зараз все, що ви повинні перевірити, це чи запущений ваш веб сайт. Відкрийте ваш браузер (Firefox, Chrome, Safari, Internet Explorer або будь-який інший) і введіть адресу: -А зараз ви повинні перевірити, чи запущений ваш веб-сайт. Відкрийте браузер (Firefox, Chrome, Safari, Internet Explorer або будь-який інший) і введіть адресу: +{% filename %}browser{% endfilename %} http://127.0.0.1:8000/ + + +Якщо ви використовуєте Chromebook і Cloud9, натомість натисніть на посилання у що спливає вікні, яке повинно було з'явитися у правому верхньому куті командного вікна, де працює вебсервер. Посилання буде виглядати приблизно так: + +{% filename %}browser{% endfilename %} + + https://.vfs.cloud9.us-west-2.amazonaws.com + + +Або на Glitch: + + https://name-of-your-glitch-project.glitch.me + + +Вітаємо! Ви щойно створили свій перший вебсайт та запустили його на вебсервері! Хіба ж це не круто? + +![Встановлено!](images/install_worked.png) -Веб-сервер забирає на себе керування командним рядком, доки ви його не зупините. Моб мати можливість виконувати нові команди, поки працює веб-сервер, відкрийте нове вікно командного рядка (терміналу) та активуйте ваш virtualenv. Щоб зупинити веб-сервер, переключіться назад до вікна, в якому він працює і використайте сполучення клавіш CTRL + C (натисніть клавіші разом) (на Windows, можливо, доведеться натиснути клавіші Ctrl + Break). +Зверніть увагу, що вікно команд може виконувати тільки одну річ за раз, а вікно команд, що ви відкрили раніше запускає вебсервер. Поки вебсервер працює і чекає додаткових вхідних запитів, термінал прийме новий текст, але не бути виконувати нові команди. -Вітаємо! Ви щойно створили свій перший веб-сайт та запустили його на веб-сервері! Хіба ж це не круто? +> Ми розглянули як працюють вебсервери у розділі **How the Internet works** -![Працює!](images/it_worked2.png) +Щоб ввести додаткові команди, поки працює вебсервер, відкрийте нове вікно терміналу та активуйте Ваше віртуальне середовище -- щоб переглянути інструкції, як відкрити друге вікно терміналу, дивіться [Introduction to the command line](../intro_to_command_line/README.md). Щоб зупинити вебсервер, перемикнутися назад до вікна, в якому він працює і натисніть CTRL+C - Control і C разом (на Windows, можливо доведеться натиснути Ctrl+Break). -Готові до наступного кроку? Час додати трішки контенту! +Готові до наступного кроку? Час створювати контент! \ No newline at end of file diff --git a/uk/django_templates/README.md b/uk/django_templates/README.md old mode 100755 new mode 100644 index aaa7ba667e3..3f25b4c034d --- a/uk/django_templates/README.md +++ b/uk/django_templates/README.md @@ -1,32 +1,40 @@ # Django шаблони -Час вивести деякі дані! Django надає нам певні допоміжні, вбудовані __шаблонні теги__ для цього. +Час вивести деякі дані! Django надає нам певні допоміжні, вбудовані **шаблонні теги** для цього. ## Що таке шаблонні теги? -Як бачите, в HTML, ви не можете помістити Python код, тому що браузери не зрозуміють його. Вони знають лише HTML. Ми знаємо, що HTML більшою мірою є статичною, в той час як Python є більш динамічною мовою. +You see, in HTML, you can't really write Python code, because browsers don't understand it. They know only HTML. We know that HTML is rather static, while Python is much more dynamic. -__Шаблонні теги Django__ дозволяють нам передавати Python-подібні речі в HTML, таким чином можна розробляти динамічні веб-сайти швидше і простіше. Ой! +**Django template tags** allow us to transfer Python-like things into HTML, so you can build dynamic websites faster. Cool! ## Шаблон для виведення списку постів -В попередньому розділі ми надали нашому шаблону список постів у змінній `posts`. А тепер відобразимо це в HTML. +В попередньому розділі ми надали нашому шаблону список постів у змінній `posts`. А тепер покажемо це в HTML. -Щоб надрукувати змінну в Django шаблоні, ми використовуємо подвійні фігурні дужки з іменем змінної всередині: +Щоб надрукувати змінну в шаблонах Django, ми використовуємо подвійні фігурні дужки з ім’ям змінної всередині, наприклад: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html {{ posts }} ``` -Спробуйте це в шаблоні `blog/templates/blog/post_list.html`. Починаючи з другого `
` до третього `
` замініть все на `{{ posts }}`. Збережіть файл і оновіть сторінку, щоб побачити результат: +Спробуйте це в шаблоні `blog/templates/blog/post_list.html`. Open it up in the code editor, and replace the existing `
` elements with `{{ posts }}`. Збережіть файл і оновіть сторінку, щоб побачити результат: + +![Figure 13.1](images/step1.png) -![Рисунок 13.1](images/step1.png) +Як можна побачити, все що ми отримали це: -Як можна побачити, все що ми отримали, це: +{% filename %}blog/templates/blog/post_list.html{% endfilename %} - , ]> +```html +, ]> +``` -Означає, що Django розуміє це як список об'єктів. Пам'ятаєте із розділу __Вступ до Python__ як ми можемо виводити списки? Звичайно, за допомогою циклу __for__! У Django шаблонах ви можете створити їх наступним чином: +Це означає, що Django розуміє його як список об’єктів. Пам’ятаєте з **Вступ до Python**, як ми можемо відображати списки? Звичайно, за допомогою циклу **for**! У Django шаблонах ви можете створити їх наступним чином: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html {% for post in posts %} @@ -36,61 +44,65 @@ __Шаблонні теги Django__ дозволяють нам передав Спробуйте це у вашому шаблоні. -![Рисунок 13.2](images/step2.png) +![Figure 13.2](images/step2.png) + +Працює! But we want the posts to be displayed like the static posts we created earlier in the **Introduction to HTML** chapter. Ви можете компонувати теги HTML і шаблонні теги. Наша частина `body` буде виглядати так: -Працює! Однак, бажано, щоб вони були виведені як статичні пости, які ми створили раніше у розділі __Вступ до HTML__. Ви можете компонувати теги HTML і шаблонні теги. Наша частина `body` буде виглядати так: +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html - + {% for post in posts %} -
-

published: {{ post.published_date }}

-

{{ post.title }}

+
+ +

{{ post.title }}

{{ post.text|linebreaksbr }}

-
+
{% endfor %} ``` -{% raw %}Все, що ви напишете між `{% for %}` та `{% endfor %}` повторюватиметься для кожного об'єкта у списку. Оновіть сторінку:{% endraw %} - -![Рисунок 13.3](images/step3.png) +Все що ви напишете між `{% for %}` та `{% endfor %}` повторюватиметься для кожного об'єкта у списку. Оновіть сторінку: -Чи помітили ви, що цього разу ми використали трохи відмінні позначення `{{ post.title }}` або `{{ post.text }}`? Ми маємо доступ до даних, що містяться в кожному полі, визначеному в нашій моделі `Post`. Також `|linebreaksbr` перенаправляє текст посту через фільтр щоб конвертувати розриви ліній в абзаци. +![Figure 13.3](images/step3.png) +Have you noticed that we used a slightly different notation this time (`{{ post.title }}` or `{{ post.text }}`)? Ми маємо доступ до даних, що містяться в кожному полі, визначеному в нашій моделі `Post`. Also, the `|linebreaksbr` is piping the posts' text through a filter to convert line-breaks into paragraphs. ## Ще одне -Було б непогано побачити як ваш сайт буде працювати в інтернеті, так? Давайте спробуєм розгорнути його в PythonAnywhere знову. Ось наступні кроки... +It'd be good to see if your website will still be working on the public Internet, right? Let's try deploying to PythonAnywhere again. Here's a recap of the steps… -* По-перше, залийте ваш код на GitHub +* First, push your code to GitHub -``` -$ git status -[...] -$ git add --all . -$ git status -[...] -$ git commit -m "Modified templates to display posts from database." -[...] -$ git push -``` +{% filename %}command-line{% endfilename %} -* Потім, увійдіть до [PythonAnywhere](https://www.pythonanywhere.com/consoles/) та перейдіть до **Bash консолі** (або запустіть нову) і виконайте команди: + $ git status + [...] + $ git add . + $ git status + [...] + $ git commit -m "Modified templates to display posts from database." + [...] + $ git push + -``` -$ cd my-first-blog -$ git pull -[...] -``` +* Потім, увійдіть назад до [PythonAnywhere](https://www.pythonanywhere.com/consoles/) та перейдіть до **Bash консолі** (або запустіть нову) і виконайте команди: + +{% filename %}PythonAnywhere command-line{% endfilename %} + + $ cd .pythonanywhere.com + $ git pull + [...] + -* Нарешті, перейдіть на вкладку [Web](https://www.pythonanywhere.com/web_app_setup/) і натисніть **Reload** (перезавантажити) у веб-додатку. +(Remember to substitute `` with your actual PythonAnywhere subdomain, without the angle-brackets.) +* Finally, hop on over to the ["Web" page](https://www.pythonanywhere.com/web_app_setup/) and hit **Reload** on your web app. (To reach other PythonAnywhere pages from the console, use the menu button in the upper right corner.) Your update should be live on https://subdomain.pythonanywhere.com -- check it out in the browser! If the blog posts on your PythonAnywhere site don't match the posts appearing on the blog hosted on your local server, that's OK. The databases on your local computer and Python Anywhere don't sync with the rest of your files. -Вітаємо! А тепер спробуйте додати новий пост у вашому Django адміністраторі (не забудьте додати published_date!), потім перезавантажте сторінку, щоб переконатись, чи з'явився новий пост. +Congrats! Now go ahead and try adding a new post in your Django admin (remember to add published_date!) Make sure you are in the Django admin for your pythonanywhere site, https://subdomain.pythonanywhere.com/admin. Then refresh your page to see if the post appears there. -Все працює, як годинник? Ми пишаємося! Відійдіть ненадовго від комп'ютера, ви заслуговуєте на перерву. :) +Works like a charm? We're proud! Step away from your computer for a bit – you have earned a break. :) -![Рисунок 13.4](images/donut.png) +![Figure 13.4](images/donut.png) \ No newline at end of file diff --git a/uk/django_urls/README.md b/uk/django_urls/README.md old mode 100755 new mode 100644 index 9054f9e351b..909ec1fed1a --- a/uk/django_urls/README.md +++ b/uk/django_urls/README.md @@ -1,122 +1,115 @@ -# Django url +# URL - адреси Django -Ми збираємося побудувати нашу першу веб-сторінку - домашню сторінку для вашого блогу! Але спочатку, давайте трохи дізнаємось про Django URL-адреси. +Ми збираємось створити нашу першу вебсторінку: домашню сторінку для Вашого блогу! Але спочатку, давайте розберемось, що таке URL-адреси Django. -## Що таке URL? +## Що таке URL - адреса? -URL - це просто веб-адреса. Відображається URL кожен раз, коли ви відвідуєте веб-сайт - це видно в адресному рядку браузера (так! `127.0.0.1:8000` - це URL! І `https://djangogirls.org` також є URL): +URL - адреса — це вебадреса. Ви можете побачити URL- адресу кожного разу, як Ви заходите на вебсайт — її видно в адресному рядку вашого браузера. (Так! `127.0.0.1:8000` - це URL - адреса! І `https://djangogirls.org` - це також URL - адреса. -![Url](images/url.png) +![URL-адреса](images/url.png) -Кожна сторінка в Інтернеті потребує свого власного URL. Таким чином ваш додаток знає, що треба показувати користувачу, який відкриває URL. В Django використовується така річ, яка називається `URLconf` (URL конфігурація). URLconf являє собою набір шаблонів, які Django намагатиметься зіставити з отриманих URL, щоб знайти правильне відображення. +Кожній сторінці в Інтернеті потрібна своя власна URL - адреса. Таким чином Ваш додаток знає, що потрібно показати користувачу, який переходить за URL - адресою. В Django ми використовуємо щось на кшталт `URLconf` (конфігурація URL - адреси). Конфігурація URL - адреси — це набір шаблонів, які Django намагатиметься зіставити з отриманими URL - адресами, щоб знайти правильну вебсторінку.   -## Як працює URL в Django? +## Як працє URL - адреса в Django? Давайте відкриємо файл `mysite/urls.py` в редакторі коду і подивимось, як він виглядає: +{% filename %}mysite/urls.py{% endfilename %} + ```python -from django.conf.urls import include, url +"""mysite URL Configuration + +[...] +""" from django.contrib import admin +from django.urls import path urlpatterns = [ - # Examples: - # url(r'^$', 'mysite.views.home', name='home'), - # url(r'^blog/', include('blog.urls')), - - url(r'^admin/', include(admin.site.urls)), + path('admin/', admin.site.urls), ] ``` -Як бачите, Django вже щось записав сюди для нас. +Як Ви бачите, Django самостійно дещо поставив для нас. + +Рядки між потрійними лапками (`'''` or `"""`) називаються рядками документів — ви можете поставити їх у верхній частині файлу, класу або методу, щоб описати, що саме він робить.   Вони не будуть керуватися Python. -Рядки, що починаються з `#` - це коментарі, тобто ці рядки не будуть запускатися Python. Досить зручно, чи не так? +URL-адреса адміністратора, яку Ви відвідали в попередньому розділі, вже тут: -URL панелі адміністратора, котрий ви відвідували у попередньому розділі вже є тут: +{% filename %}mysite/urls.py{% endfilename %} ```python - url(r'^admin/', include(admin.site.urls)), + path('admin/', admin.site.urls), ``` -Це означає, що для кожного URL, що починається з `admin/` Django знаходитиме відповідне відображення - *view*. У даному випадку ми включаємо багато адміністраторських URL, отже не все запаковується в цей маленький файл, що є більш читабельним і акуратнішим. - -## Regex - -Хіба вам не цікаво, яким чином Django створює відповідності між URL і відображеннями? Гаразд, ця частина досить хитра. Django використовує `regex`, що є скороченням від "regular expressions" (регулярні вирази). Regex має багато (багато!) правил, що формують шаблон пошуку. Оскільки регулярні вирази є продвинутою темою, ми не будемо вникати в деталі їх роботи. - -Якщо ви все ще хочете зрозуміти, як ми створили шаблони, ось приклад процесу - нам потрібно буде тільки обмежена підмножина правил для того, щоб виразити потрібний шаблон, а саме: - - ^ для початку тексту - $ для кінця тексту - \d для цифри - + щоб позначити, що попередній символ має бути повторений мінімум один раз - () для захоплення частини шаблону +Цей рядок означає, що для кожної URL-адреси, яка починається з `admin/`, Django знайде відповідний *view*. В цьому випадку ми включаємо багато URL-адрес адміністратора, щоб вони всі не були закладені в один невеликий файл – так його легше читати та він стає чистіший. -Все інше у визначенні url буде прийматися як є. +## Ваша перша URL-адреса Django! -Тепер уявіть, що у вас є сайт з такою адресою: `http://www.mysite.com/post/12345/`, де `12345` - це номер вашого посту. +Час створити нашу першу URL-адресу! Ми хочемо, щоб «http://127.0.0.1:8000/» став домашньою сторінкою нашого блогу та відображав список публікацій. -Написання окремих відображень для усіх номерів постів було б дійсно нестерпним. За допомогою регулярних виразів ми можемо створити шаблон, який відповідає url і витягти номер для нас: `^post/(\d+)/$`. Давайте розберемо його по частинах, щоб побачити, що ми тут робимо: +Ми також хочемо, щоб файл `mysite/urls.py` був чистим, тому ми імпортуємо URL-адреси з нашого додатку `blog` до головного файлу `mysite/urls.py.

-* **^post/** говорить Django взяти що-небудь, що має `post/` на початку url (зразу після `^`) -* **(\d+)** означає, що буде число (одне або декілька цифр), і ми хочемо, щоб число захопилось і вибралось -* **/** вказує Django, що наступним символом має бути `/` -* **$** далі позначає кінець URL-адреси, а це означає, що під шаблон підходять лише ті рядки, які закінчуються на `/` +

Далі додайте рядок, який імпортує blog.urls`. Вам також потрібно буде змінити рядок `from django.urls…`, оскільки тут ми використовуємо функцію `include`, тому вам потрібно буде додати цей імпорт до цього рядка. +Ваш файл `mysite/urls.py` тепер повинен виглядати наступним чином: -## Ваш перший Django url! - -Час створити наш перший URL! Ми хочемо, щоб 'http://127.0.0.1:8000/' був домашньою сторінкою нашого блогу і виводив список постів. - -Також ми б хотіли підтримувати порядок у файлі `mysite/urls.py`, отже імпортуємо url з нашого додатку `blog` у файл `mysite/urls.py`. - -Вперед, видаліть закоментовані рядки (рядки, що починаються з `#`) та додайте рядок, що імпортує `blog.urls` до головного url (`''`). - -Ваш файл `mysite/urls.py` повинен наразі мати такий вигляд: +{% filename %}mysite/urls.py{% endfilename %} ```python -from django.conf.urls import include, url from django.contrib import admin +from django.urls import path, include urlpatterns = [ - url(r'^admin/', include(admin.site.urls)), - url(r'', include('blog.urls')), + path('admin/', admin.site.urls), + path('', include('blog.urls')), ] ``` -Django тепер перенаправлятиме усе, що надходить на 'http://127.0.0.1:8000/' до `blog.urls` і шукатиме там подальші інструкції. - -Для запису регулярних виразів у Python використовується символ `r` перед стрічкою. Це підказка для інтерпретатора, що рядок може містити спеціальні символи, які використовуються в регулярних виразах. - +Тепер Django буде перенаправляти все, що надходить в 'http://127.0.0.1:8000/', на `blog.urls` і шукатиме там подальші інструкції. ## blog.urls -Створіть новий порожній файл `blog/urls.py`. Добре! Додайте наступні перші два рядки: +Створіть новий порожній файл з іменем `urls.py` у каталозі `blog` і відкрийте його в редакторі коду. Добре! Додайте ці перші два рядки: + +{% filename %}blog/urls.py{% endfilename %} ```python -from django.conf.urls import url +from django.urls import path from . import views ``` -Тут ми лише імпортуємо методи Django і всі наші відображення з додатку `blog` (у нас ще немає жодного, але ми повернемося до цього через хвилину!) +Тут ми імпортуємо функцію Django `path` і всі наші `views` з додатка `blog`. (У нас їх ще немає, але ми повернемося до цього за хвилину!) + +Після цього ми можемо додати наш перший шаблон URL-адреси: -Після цього, ми можемо додати наш перший URL шаблон: +{% filename %}blog/urls.py{% endfilename %} ```python urlpatterns = [ - url(r'^$', views.post_list, name='post_list'), + path('', views.post_list, name='post_list'), ] ``` -Як бачите, ми присвоюємо відображення із назвою `post_list` значенню URL `^$`. Цей регулярний вираз буде перевіряти рядок на `^` (початок рядка) та `$` (кінець) - тому тільки порожній рядок буде відповідати цим вимогам. Це правильно, тому що в механізмі Django URL, вираз ' http://127.0.0.1:8000 /' не є частиною URL-адреси. Цей шаблон показуватиме для Django, що `views.post_list` є правильним місцем для переходу, якщо хтось введе ваш сайт за адресою 'http://127.0.0.1:8000/'. +Як бачимо, зараз ми присвоюємо `view` під назвою `post_list` до кореневої URL-адреси. Цей шаблон URL-адреси відповідатиме порожньому рядку, а розпізнавач URL-адрес Django ігноруватиме ім’я домену (тобто http://127.0.0.1:8000/), яке стоїть спереду URL-адреси. Цей шаблон показуватиме Django, що `views.post_list` є правильним місцем для переходу, якщо хтось зайде на Ваш вебсайт за адресою 'http://127.0.0.1:8000/'. -На останок, `name='post_list'` - це назва URL, який використовуватиметься для ідентифікації потрібного відображення (в'ю). Це може бути ім'ям потрібного нам відображення (в'ю), або взагалі чимось іншим. Ми буде використовувати іменовані URL-адреси, протягом всього проекту, тому важливо, давати ім'я кожному URL у застосунку. Ми також повинні намагатися давати URL-адресам якомога простіші та унікальні імена, і так, щоб їх було легко запам'ятати. +Ш останнє, `name='post_list'` є назвою URL-адреси, яка буде використовуватися для ідентифікації огляду. Це може бути ім'ям потрібного нам огляду або ж чимось зовсім іншим. Ми продовжимо використовувати названі URL-адреси в цьому проєкті, тому важливо назвати кожну URL-адресу в програмі. Нам також потрібно назвати URL-адреси так, щоб вони були унікальними й легко запам’ятовувалися. -Усе гаразд? Відкрийте http://127.0.0.1:8000/ у браузері, щоб побачити результат. +Якщо ви спробуєте зараз перейти на http://127.0.0.1:8000/, Ви побачите щось на кшталт «вебсторінка недоступна». Це тому, що сервер (пам’ятаєте, ми ввели `runserver`?) більше не працює. Подивіться у вікні консолі Вашого сервера, щоб дізнатися, чому. -![Error](images/error1.png) +{% filename %}{{ warning_icon }} command-line{% endfilename %} -Що, тут більше немає повідомлення "It works"? Не хвилюйтесь, це просто сторінка із помилкою, нічого боятися! Вони є насправді дуже корисними: + return _bootstrap._gcd_import(name[level:], package, level) + File "", line 1030, in _gcd_import + File "", line 1007, in _find_and_load + File "", line 986, in _find_and_load_unlocked + File "", line 680, in _load_unlocked + File "", line 850, in exec_module + File "", line 228, in _call_with_frames_removed + File "/Users/ola/djangogirls/blog/urls.py", line 5, in + path('', views.post_list, name='post_list'), + AttributeError: module 'blog.views' has no attribute 'post_list' + -Можете прочитати тут: __no attribute 'post_list'__. Чи *post_list* не нагадує вам про щось? Це назва нашого відображення! Це означає, що все знаходиться на місці, але ми просто ще не створили наше *відображення*. Не переймайтесь, ми його отримаємо. +Ваша консоль показує помилку, але не хвилюйтеся – це насправді дуже добре: це говорить про те, що **attribute 'post_list'** відсутній. Це назва *view*, яке Django намагається знайти та використати, але ми його ще не створили. На цьому етапі `/admin/` також не буде працювати. Не хвилюйтеся, про це ми поговоримо також. Якщо Ви бачите інше повідомлення про помилку, спробуйте перезавантажити Ваш вебсервер. Для цього у вікні консолі, де запущено вебсервер, зупиніть його, натиснувши Ctrl+C (клавіші Control і C разом). У Windows, можливо, потрібно натиснути Ctrl+Break. Потім Вам потрібно перезавантажити вебсервер, запустивши команду `python manage.py runserver`. -> Якщо бажаєте дізнатися більше про Django URLconf, зверніться до офіційної документації: https://docs.djangoproject.com/en/1.11/topics/http/urls/ +> If you want to know more about Django URLconfs, look at the official documentation: https://docs.djangoproject.com/en/3.2/topics/http/urls/ \ No newline at end of file diff --git a/uk/django_views/README.md b/uk/django_views/README.md old mode 100755 new mode 100644 index 6659604e69b..c67956863ea --- a/uk/django_views/README.md +++ b/uk/django_views/README.md @@ -1,14 +1,16 @@ # Django відображення - час творити! -Час позбутися помилки, створеної в попередньому розділі :) +Час позбутися помилки, створеної в останньому розділі! :) -Відображення - *view* - це місце, в якому ми закладаємо "логіку" нашої програми. Воно запитує інформацію з `моделі`, яку ми створили раніше і передає його до `шаблону`. Ми створимо шаблон в наступному розділі. Відображення - це просто методи Python, трохи складніші за ті, які ми робили у розділі __Вступ до Python__. +Відображення - *view* -- це місце, в якому ми закладаємо "логіку" нашої програми. Воно запитує інформацію з `моделі`, яку ми створили раніше і передає його до `шаблону`. Ми створимо шаблон в наступному розділі . Перегляди — це лише функції Python, які трохи складніші, ніж ті, які ми писали у розділі **Вступ до Python**. Відображення розташовані у файлі `views.py`. Додамо наші відображення до файлу `blog/views.py`. ## blog/views.py -OK, давайте відкриємо цей файл і подивимось що тут: +Добре, давайте відкриємо цей файл у нашому редакторі коду і подивимося, що там : + +{% filename %}blog/views.py{% endfilename %} ```python from django.shortcuts import render @@ -16,22 +18,27 @@ from django.shortcuts import render # Create your views here. ``` -Не так багато поки що. Найпростіший вид може бути таким. +Поки що тут ще майже нічого немає. + +Пам’ятайте, що рядки, які починаються з `#`, є коментарями, а це означає, що Python не запускатиме ці рядки. + +Давайте створимо *view*, як пропонує коментар. Додайте наступний мінімальний огляд нижче: + +{% filename %}blog/views.py{% endfilename %} ```python def post_list(request): return render(request, 'blog/post_list.html', {}) ``` +Як бачите, ми створили функцію (`def`) під назвою `post_list`, яка приймає `запит` і `поверне` значення, яке він отримує від виклику іншої функції `render`, яка відтворить (збере разом) наш шаблон `blog/post_list.html`. -Як бачимо, ми створили метод (`def`) із назвою `post_list`, що приймає як аргумент запит - `request` і повертає метод `render`, що активує (компілює) наш шаблон `blog/post_list.html`. - -Збережіть файл, перейдіть до http://127.0.0.1:8000/ і подивіться, що ми отримали. +Збережіть файл, перейдіть на http://127.0.0.1:8000/, щоб подивитися, що ми отримали. Інша помилка! Прочитайте у чому цього разу справа: -![Error](images/error.png) +![Помилка](images/error.png) -Цього разу усе просто: *TemplateDoesNotExist*.Виправимо це і створимо шаблон в наступному розділі! +Це свідчить про те, що сервер знову працює, принаймні, але все одно виглядає не так, чи не так? Не хвилюйтеся, це просто сторінка з помилкою, нічого боятися! Як і повідомлення про помилки в консолі, вони насправді є дуже корисними. Ви можете побачити, що *TemplateDoesNotExist*. Давайте виправимо цю помилку та створимо шаблон у наступному розділі! -> Дізнатися більше про Django відображення можна, звернувшись до офіційної документації: https://docs.djangoproject.com/en/1.11/topics/http/views/ +> Learn more about Django views by reading the official documentation: https://docs.djangoproject.com/en/3.2/topics/http/views/ \ No newline at end of file diff --git a/uk/dynamic_data_in_templates/README.md b/uk/dynamic_data_in_templates/README.md old mode 100755 new mode 100644 index 8f0daf06845..6950f64bd39 --- a/uk/dynamic_data_in_templates/README.md +++ b/uk/dynamic_data_in_templates/README.md @@ -1,12 +1,14 @@ # Динамічні дані в шаблонах -Маємо різні шматочки на своїх місцях: модель `Post` визначено в `models.py`, маємо `post_list` у `views.py`, а також відповідний шаблон. Однак, яким чином ми змусимо наші пости з'явитися в HTML шаблоні? Оскільки це те, чого ми хочемо: взяти деякий контент (моделі збережені в базі даних) і вивести його в гарному вигляді на нашому шаблоні, правда ж? +Маємо різні шматочки на своїх місцях: модель `Post` визначено в `models.py`, маємо `post_list` у `views.py`, а також відповідний шаблон. Однак, яким чином ми змусимо наші пости з'явитися в HTML шаблоні? Оскільки це те, що ми хочемо зробити – взяти деякий контент (моделі, збережені в базі даних) і відобразити його в гарному вигляді в нашому шаблоні, чи не так? -Це саме те, що покликані робити відображення: з'єднаємо моделі і шаблони. В нашому відображенні `post_list` нам потрібно взяти моделі, які ми хочемо зобразити, і передати їх до шаблону. Отже, в основному, у секції відображення - *view* ми вирішуємо що (модель) буде виведено в шаблоні. +Це саме те, що покликані робити відображення: з'єднаємо моделі і шаблони. У нашому `post_list` *view* нам потрібно буде взяти моделі, які ми хочемо відобразити, і перенести їх у шаблон. У *view* ми вирішуємо, що (модель) буде відображатися в шаблоні. -Добре, отже як ми цього досягнемо? +Добре, як же ми цього досягнемо? -Нам треба відкрити наш `blog/views.py`. Таким чином, відображення `post_list` виглядає на кшталт: +Нам потрібно відкрити наш `blog/views.py` у нашому редакторі коду. Таким чином, `post_list` *view* виглядає так: + +{% filename %}blog/views.py{% endfilename %} ```python from django.shortcuts import render @@ -15,26 +17,34 @@ def post_list(request): return render(request, 'blog/post_list.html', {}) ``` -Пам'ятаєте, як ми говорили про включення коду написаного в різних файлах? Тепер настав момент, коли ми повинні включити модель написану в `models.py`. Додаймо рядок `from .models import Post`: +Пам'ятаєте як ми говорили про включення коду написаного в різних файлах? Настав момент, коли ми повинні включити модель, яку ми написали в `models.py`. Додамо рядок `з .models import Post` так: + +{% filename %}blog/views.py{% endfilename %} ```python from django.shortcuts import render from .models import Post ``` -Крапка після `from` означає *поточна директорія* або *поточний додаток*. Оскільки `views.py` і `models.py` розташовані в одній і тій же папці, можемо просто використовувати `.` і ім'я файлу (без `.py`). Далі імпортуємо ім'я моделі (`Post`). +Крапка перед `models` означає *поточний каталог* або *поточний додаток*. Обидві функції `views.py` і `models.py` знаходяться в одному каталозі. Це означає, що ми можемо використовувати `.` і ім’я файлу (без `.py`). Далі ми імпортуємо ім'я моделі (`Post`). -А що далі? Щоб вилучити реальні пости з моделі `Post`, нам потрібна певна річ, що називається `QuerySet`. +Але що далі? Щоб вилучити реальні дописи блогу з моделі `Post`, нам потрібно дещо під назвою `QuerySet`. ## QuerySet -Ви маєте вже бути ознайомлені із роботою QuerySets. Ми говорили про це у розділі [Django ORM (QuerySets)](../django_orm/README.md). +Ви вже повинні бути ознайомлені з тим, як працюють QuerySets. Ми говорили про них у [розділі Django ORM (QuerySets)](../django_orm/README.md). + +Отже, тепер ми хочемо, щоб опубліковані дописи в блозі були відсортовані за `датою_публікування`, чи не так? Ми вже робили це в розділі QuerySets! -Отже, наразі ми зацікавлені у списку опублікованих і відсортованих за параметром `published_date` блог постів, чи не так? Ми вже робили це у розділі QuerySets! +{% filename %}blog/views.py{% endfilename %} - Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date') +```python +Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date') +``` -А тепер вставимо цей шматок коду у файл `blog/views.py` додавши його до функції `def post_list(request)`: +Отже, давайте відкриємо файл `blog/views.py` у редакторі коду та додамо цей фрагмент коду до функції `def post_list(request)`, але не забудьте спочатку додати `часовий пояс імпорту з django.utils`: + +{% filename %}blog/views.py{% endfilename %} ```python from django.shortcuts import render @@ -46,16 +56,19 @@ def post_list(request): return render(request, 'blog/post_list.html', {}) ``` -Зазначте, будь ласка, що ми створюємо *змінну* для нашого QuerySet: `posts`. Сприймайте її як ім'я для QuerySet. З цього моменту ми можемо посилатися на неї через це ім'я. +Щоб відобразити наш QuerySet у нашому списку публікацій у блозі, нам залишилося зробити дві речі: -Крім того, код використовує функцію `timezone.now()`, а значить, ми повинні імпортувати `timezone`. +1. Перенесіть QuerySet `posts` до контексту шаблону, змінивши виклик функції `render`. Ми зараз це зробимо. +2. Змініть шаблон, щоб відобразити `публікації` QuerySet. Ми розглянемо це в наступному розділі. -Остання пропущена частина - передача QuerySet `posts` шаблону (розглянемо, як це вивести в наступному розділі). +Зазначте, будь ласка, що ми створюємо *змінну* для нашого QuerySet: `posts`. Сприймайте її як ім'я для QuerySet. З цього моменту ми можемо посилатися на неї через це ім'я. -У функції `render` ми вже маємо параметр `request` (тобто усе, що ми отримуємо від користувача через Інтернет) і файл шаблону `'blog/post_list.html'`. Останній параметр, котрий виглядає як: `{}` - це місце, в якому ми можемо додавати певні речі для використання у шаблоні. Ми повинні дати їм імена (ми обмежились ім'ям `'posts'` наразі :)). Це має виглядати як: `{'posts': posts}`. Прохання звернути увагу, що частина перед `:` є рядком; вам необхідно взяти це у лапки `''`. +У функції `render` у нас є один параметр `request` (все, що ми отримуємо від користувача через Інтернет) і інший, що надає шаблону файл (`'blog/post_list.html '`). Останній параметр, `{}`, є місцем, куди ми можемо додати певні речі, які шаблон може використовувати. Ми повинні дати їм імена (ми обмежились ім'ям `'posts'` наразі). :) Це має виглядати як: `{'posts': posts}`. Зверніть увагу, що частина перед `:` є рядком; Вам потрібно взяти цю частину в лапки: `''`. Отже, врешті-решт наш файл `blog/views.py` матиме наступний вигляд: +{% filename %}blog/views.py{% endfilename %} + ```python from django.shortcuts import render from django.utils import timezone @@ -68,4 +81,4 @@ def post_list(request): Це все! Час повернутись назад до нашого шаблону і вивести QuerySet! -Якщо бажаєте дізнатись трохи більше про QuerySets в Django, зазирніть сюди: https://docs.djangoproject.com/en/1.11/ref/models/querysets/ +Want to read a little bit more about QuerySets in Django? You should look here: https://docs.djangoproject.com/en/3.2/ref/models/querysets/ \ No newline at end of file diff --git a/uk/extend_your_application/README.md b/uk/extend_your_application/README.md old mode 100755 new mode 100644 index 189c257df11..d81718ea787 --- a/uk/extend_your_application/README.md +++ b/uk/extend_your_application/README.md @@ -1,177 +1,228 @@ +{% set warning_icon = '' %} + # Розширте свою програму -Ми вже завершили усі кроки, необхідні для створення нашого сайту: знаємо як написати модель, url, відображення та шаблон. А також знаємо про те, як зробити наш сайт гарнішим. +Ми вже завершили всі етапи необхідні для створення нашого сайту: ми знаємо як написати модель, адресу URL, вигляд та шаблон. Ми також знаємо як зробити сайт привабливим. Час попрактикуватись! -Перша потрібна для нашого блогу річ це, очевидно, сторінка для відображення одного посту, чи не так? +Перша річ, яка має бути у нашому блозі - це, очевидно, сторінка, що відображує один пост, правильно? -У нас вже є модель `Post`, отже? не треба нічого додавати до `models.py`. +Ми вже маємо модель посту`, тому не потрібно нічого додавати до models.py`. ## Створюємо в шаблоні посилання на сторінку посту -Почнемо із додавання посилання в `blog/templates/blog/post_list.html`. Таким чином, матимемо: +Ми розпочнемо із додавання посилання всередині `blog/templates/blog/post_list.html` файлу. Відкрийте його в редакторі коду і поки що воно має виглядати так: {% filename %}blog/templates/blog/post_list.html{% endfilename %} + ```html {% extends 'blog/base.html' %} {% block content %} {% for post in posts %} -

-
+
+
-

{{ post.title }}

+ +

{{ post.title }}

{{ post.text|linebreaksbr }}

-
+ {% endfor %} {% endblock %} - ``` -{% raw %}Ми хочемо, щоб в списку постів заголовок посилався на сторінку детальної інформації про пост. Давайте змінимо `

{{ post.title }}

` так, щоб вийшло посилання на пост:{% endraw %} +{% raw %}Ми хочемо, щоб в списку постів в заголовку було посилання на сторінку детальної інформації про пост. Давайте змінимо `

{{ post.title }}

` так, щоб було посилання на сторінку з детальною інформацією про пост:{% endraw %} + +{% filename %}{{ warning_icon }} blog/templates/blog/post_list.html{% endfilename %} ```html -

{{ post.title }}

+

{{ post.title }}

``` -{% raw %}Саме час пояснити цей дивний запис `{% url 'post_detail' pk=post.pk %}`. Як можна було очікувати, `{% %}` означає, що ми використовуємо шаблонні теги Django. Цього разу ми використаєм один з них, який створить URL для нас!{% endraw %} +{% raw %}Час пояснити дивний запис `{% url 'post_detail' pk=post.pk %}`. Як і очікувалось, `{% %}` означає, що ми використовуємо шаблонні теги Django. На цей раз ми використаємо один, який створить адресу URL для нас! -`blog.views.post_detail` - це шлях до відображення `post_detail`, яке ми бажаємо створити. Зауважте, будь ласка, що: `blog` - це ім'я нашого додатку (папка `blog`), `views` взято з імені файлу `views.py` і остання частина - `post_detail` - це ім'я відображення. +`post_detail` частина означає, що Django буде очікувати адресу URL у `blog/urls.py` з назвою=post_detail -Тепер, коли перейдемо на: http://127.0.0.1:8000/, отримаємо помилку (як і очікувалось, оскільки у нас немає URL або потрібного *вигляду* (в'ю) для `post_detail`). Він буде виглядати наступним чином: +А як щодо `pk=post.pk`? `pk` - це скорочення від первинного ключа, що є унікальним ідентифікатором для кожного запису в базі даних. Кожна модель Django має поле, яке виступає як первинний ключ і будь-яку іншу назву воно маже мати, це також може називатися "pk". Тому що ми не вказали основного ключа в моделі `поста`, Django створює одне для нас (за замовчуванням, поле з назвою "id", що збільшується на усі записи, наприклад 1,2,3) і додає це поле в кожну з наших записів. Ми маємо доступ до первинного ключа, записуючи `post.pk`, так само як ми отримуємо доступ до інших полів (`назва`,`автор` і т.д.) у нашому об'єкті `пост`! -![NoReverseMatch error](images/no_reverse_match2.png) +Тепер, коли ми переходимо до http://127.0.0.1:8000/, ми отримуємо помилку (як і оікувалось, оскільки у нас немає адреси URL або потрібного *вигляду* для `post_detail`. Це буде виглядати наступним чином: + +![ +Помилка NoReverseMatch +](images/no_reverse_match2.png) ## Створюєм адресу URL для деталей запису -Давайте створимо URL в `urls.py` для нашого відображення `post_detail`! +Давайте створимо адресу URL на `urls.py` для нашого *вигляду* `post_detail`! + +Ми хочемо, щоб наш перший пост був доступний за такою адресою **URL**: http://127.0.0.1:8000/post/1/ -Ми хочемо, щоб наш перший пост був доступний за такою **URL-адресою**: http://127.0.0.1:8000/post/1/ +Давайте створимо адресу URL в файлі `blog/urls.py` і вкажемо Django на *вигляд* з назвою `post_detail`, який буде відображати пост цілком. Відкрийте файл `blog/urls.py` в редакторі коду і додайте рядок `path('post//', views.post_detail, name='post_detail'),` так щоб файл виглядав так: -У файлі `blog/urls.py` вкажемо Django, де взяти відображення для запису блогу, яке називається `post_detail`. Додамо рядок `url(r'^post/(?P[0-9]+)/$', views.post_detail, name='post_detail'),`у файл `blog/urls.py`. Це має виглядати якось так: +{% filename %}{{ warning_icon }} blog/urls.py{% endfilename %} ```python -from django.conf.urls import url +from django.urls import path from . import views urlpatterns = [ - url(r'^$', views.post_list, name='post_list'), - url(r'^post/(?P[0-9]+)/$', views.post_detail, name='post_detail'), + path('', views.post_list, name='post_list'), + path('post//', views.post_detail, name='post_detail'), ] ``` -Ця частина `^post/(?P[0-9]+)/$` виглядає страшно, але не хвилюйтеся - зараз ми все пояснимо: -- вона починається з `^` - цей символ означає "початок", -- далі `post/` означає, що після початку, URL-адреса має містити слова **post** та **/**. Все йде добре. -- `(?P[0-9]+)` - ця частина хитріша. Вона означає, що Django візьме усе, що ви тут розмістите і передасть це до відображення як змінну із ім'ям `pk`. `[0-9]` також повідомляє нам про те, що це може бути лише цифрою, а не літерою (будь-яке значення між 0 та 9). `+` означає, що тут має бути один або більше символів. Таким чином, щось на зразок `http://127.0.0.1:8000/post//` є неприйнятним, однак `http://127.0.0.1:8000/post/1234567890/` цілком! -- `/` - далі нам потрібно знову __/__ -- `$` - "кінець"! +Ця частина `post/` визначає шаблон адреси URL - ми пояснимо це вам: + +- `post` означає, що URL-адреса має починатися зі слова **post** з такою назвою ****. Все йде правильно. +- `` - ця частина складніша. Це означає, що Django очікує ціле значенння і передасть його до вигляду як змінну `pk`. +- `/` - тоді нам знадобиться **/** після завершення URL-адреси. + +Це означає, що якщо ви введете `http://127.0.0.1:8000/post/5/`, Django зрозуміє, що ви шукаєте відображення із назвою `post_detail` і передає цьому відображенню інформацію, що `pk` дорівнює `5`. -Це означає, що якщо введете `http://127.0.0.1:8000/post/5/`, Django зрозуміє, що ви шукаєте відображення із назвою `post_detail` і передає цьому відображенню інформацію, що `pk` дорівнює `5`. +Гаразд, ми додали новий шаблон URL-адрес до `blog/urls.py`! Оновімо сторінку: http://127.0.0.1:8000/ Бум!  Сервер знову перестав працювати. Подивіться на консоль – як і очікувалося, там ще одна помилка! -`pk` - скорочення для первинного ключа - `primary key`. Це ім'я часто використовується в Django проектах. Однак, можете назвати вашу змінну як вам до вподоби (пам'ятайте: маленькі літери і `_` замість пробілів!). Наприклад, замість `(?P[0-9]+)` можемо мати змінну `post_id`, і, таким чином, ця частина буде виглядати як: `(?P[0-9]+)`. +{% filename %}{{ warning_icon }} command-line{% endfilename %} -Добре, ми додали новий шаблон URL для `blog/urls.py`! Давайте перезавантажимо сторінку: http://127.0.0.1:8000/ Опаньки! Знову помилка! Як ми і очікували. + return _bootstrap._gcd_import(name[level:], package, level) + File "", line 1030, in _gcd_import + File "", line 1007, in _find_and_load + File "", line 986, in _find_and_load_unlocked + File "", line 680, in _load_unlocked + File "", line 850, in exec_module + File "", line 228, in _call_with_frames_removed + File "/Users/ola/djangogirls/blog/urls.py", line 6, in + path('post//', views.post_detail, name='post_detail'), + AttributeError: module 'blog.views' has no attribute 'post_detail' + -![AttributeError](images/attribute_error2.png) +Пригадуєте, який наступний крок? Потрібно додати огляд! -Пам'ятаєте наступний крок? Звісно: треба додати відображення! +## Додамо деталі відображення запису -## Додамо деталі для відображення запису +Цього разу нашій функції*огляд* надано додатковий параметр - `pk`. Наш *огляд* має вилучити його, чи не так? Тому ми визначимо нашу функцію як `def post_detail(request, pk):`. Зверніть увагу, що цей параметр повинен мати те саме ім’я, яке ми вказали в `urls` (`pk`). Також зверніть увагу і на те, що пропуск цієї змінної є неправильним і призведе до помилки! -Цього разу наше відображення отримує додатковий параметр - `pk`. Наше відображення має вилучити його, правда ж? Отже, визначимо нашу функцію як `def post_detail(request, pk):`. Зауважте, що треба використовувати точно таке ж ім'я, як ми визначили в urls (`pk`). Неправильно нехтувати цією змінною, це призведе до помилки! +Тепер, ми б хотіли отримати одну-єдину публікацію в блозі. Для цього ми можемо використовувати набори запитів, наприклад: -А тепер, ми хотіли б додати один-єдиний пост. Щоб зробити, це можемо скористатися наступним запитом до бази даних: +{% filename %}{{ warning_icon }} blog/views.py{% endfilename %} - Post.objects.get(pk=pk) +```python +Post.objects.get(pk=pk) +``` -Однак, цей код містить проблеми. Якщо немає жодного поста із заданим первинним ключем (`pk`), ми отримаємо мегажахливу помилку! +Однак, в цьому коді є проблема. Якщо немає `пудблікації` із заданим `первинним ключем` (`pk`), ми отримаємо жахливу помилку! ![DoesNotExist error](images/does_not_exist2.png) -Ми цього не хочемо! Звичайно, Django надає деякі інструменти, що будуть обробляти це для нас: `get_object_or_404`. У випадку, якщо немає постів із заданим `pk`, виведеться більш приємна сторінка (так звана сторінка `Page Not Found 404`). +Ми цього не хочемо! Але, на щастя, Django має деякі інструменти, які впораються з цим без нас: `get_object_or_404`. У випадку, якщо немає `Публікації` із заданим `pk`, відобразиться набагато краща сторінка, так звана `Page Not Found 404`. + +![Сторінку не знайдено](images/404_2.png) + +Хороша новина полягає в тому, що Ви можете створити свою власну сторінку `Сторінку не знайдено` і зробити її настільки гарною, наскільки Вам заманеться. Однак, зараз цей крок не є надто важливим, тому ми опустимо його. -![Page not found](images/404_2.png) +Гаразд, час додати *огляд* до нашого файлу `views.py`! -Хороші новини полягають в тому, що можна створити свою власну сторінку `Page not found` і зробити її настільки гарною, наскільки ви захочете. Однак, це не є надто важливим на даний момент, тому пропустимо цей крок. +У `blog/urls.py` ми створили правило URL-адреси з ім'ям `post_detail`, яке посилається на огляд під назвою `views.post_detail`. Це означає, що Django очікуватиме функцію огляду під назвою `post_detail` всередині `blog/views.py`. -Добре, час додати відображення у наш файл `views.py`! +Нам слід відкрити `blog/views.py` у редакторі коду та додати наступний код поряд з іншими рядками `from`: -Нам треба відкрити `blog/views.py` і додати наступний код: +{% filename %}blog/views.py{% endfilename %} - from django.shortcuts import render, get_object_or_404 +```python +from django.shortcuts import render, get_object_or_404 +``` -Поряд із іншими рядками `from`. А в кінці файлу додамо наше відображення: +І в кінці файлу ми додамо наш *огляд*: - def post_detail(request, pk): - post = get_object_or_404(Post, pk=pk) - return render(request, 'blog/post_detail.html', {'post': post}) +{% filename %}blog/views.py{% endfilename %} -Так. Прийшла пора оновити сторінку: http://127.0.0.1:8000 / +```python +def post_detail(request, pk): + post = get_object_or_404(Post, pk=pk) + return render(request, 'blog/post_detail.html', {'post': post}) +``` -![Post list view](images/post_list2.png) +Так. Прийшов час оновити сторінку: http://127.0.0.1:8000 / -Спрацювало! Але що ж трапиться, коли ви натиснете на посилання в заголовку поста? +![Перегляд списку публікацій](images/post_list2.png) + +Спрацювало! Але що ж відбудеться, коли Ви клікните на посилання в заголовку публікації? ![TemplateDoesNotExist error](images/template_does_not_exist2.png) -О, ні! Інша помилка! Але ж ми вже знаємо, як із цим поводитись, чи не так? Потрібно додати шаблон! +О ні! Ще одна помилка! Але ми вже знаємо, що потрібно робити в такому випадку, чи не так? Нам потрібно додати шаблон! + +## Створюємо шаблон для деталей публікації -## Створюємо шаблон для деталей запису +Створимо файл у `blog/templates/blog`, назвемо його `post_detail.html` і відкриємо його в редакторі коду. -Створимо файл в `blog/templates/blog` і назвемо його `post_detail.html`. +Введіть наступний код: -Це буде виглядати так: +{% filename %}blog/templates/blog/post_detail.html{% endfilename %} ```html {% extends 'blog/base.html' %} {% block content %} -
+
{% if post.published_date %} -
+
+ {% endif %} -

{{ post.title }}

+

{{ post.title }}

{{ post.text|linebreaksbr }}

-
+ {% endblock %} ``` -Знову розширюємо `base.html`. Всередині блоку `content` ми хотіли б відобразити такі параметри як: published_date (якщо існує), title і text. Але мусимо обговорити певні важливі речі, правда ж? +Ми знову розширюємо `base.html`. У блоці `content` ми хочемо показати дату публікації (якщо вона існує), назву та текст посту. Але ми мусимо обговорити певні важливі речі, чи не так? -{% raw %}`{% if ... %} ... {% endif %}` - це шаблонний тег, який можна використовувати, коли ми бажаємо перевірити дещо (пам'ятаєте `if ... else ..` з розділу __Вступ до Python__?). У цьому випадку ми хочемо перевірити, чи дата запису `published_date` не порожня.{% endraw %} +{% raw %}`{% if ... %} ... {% endif %}` - це тег шаблону, який ми можемо використовувати, коли хочемо щось перевірити. (Запам'ятати `, якщо ... ще ...` з **Вступ до розділу Python**?) У цьому сценарії ми хочемо перевірити, чи `published_date` не порожня.{% endraw %} -Окей, можемо перезавантажити нашу сторінку і побачити, чи повідомлення `Page not found` тепер зникло. +Гаразд, ми можемо оновити нашу сторінку та перевірити, чи зник `TemplateDoesNotExist`. ![Post detail page](images/post_detail2.png) -Йой! Працює! +Ура! Працює! -## Ще одне: розгортання! +# Час розгортання! -Було б добре переконатись, що ваш сайт буде працювати на PythonAnywhere, вірно? Спробуймо зробити розгортання ще раз. +Було б добре перевірити, чи Ваш вебсайт все ще працює на PythonAnywhere, вірно? Давайте спробуємо розгорнути його ще раз. -``` -$ git status -$ git add --all . -$ git status -$ git commit -m "Added view and template for detailed blog post as well as CSS for the site." -$ git push -``` +{% filename %}command-line{% endfilename %} -* Тоді в [Bash консолі PythonAnywhere](https://www.pythonanywhere.com/consoles/): + $ git status + $ git add . + $ git status + $ git commit -m "Added view and template for detailed blog post as well as CSS for the site." + $ git push + -``` -$ cd my-first-blog -$ source myvenv/bin/activate -(myvenv)$ git pull -[...] -(myvenv)$ python manage.py collectstatic -[...] -``` +Потім у [ Bash консолі PythonAnywhere](https://www.pythonanywhere.com/consoles/): + +{% filename %}командний рядок PythonAnywhere{% endfilename %} + + $ cd ~/.pythonanywhere.com + $ git pull + [...] + + +(Не забудьте замінити `` своїм фактичним субдоменом PythonAnywhere без кутових дужок.) + +## Оновлення статичних файлів на сервері + +Сервери, такі як PythonAnywhere, люблять поводитись з "статичними файлами" (наприклад, файли CSS) інакше, аніж з файлами Python, оскільки вони можуть оптимізувати їх для швидшого завантаження. Як результат, щоразу, коли ми вносимо зміни до наших файлів CSS, нам потрібно запустити додаткову команду на сервері, щоб сервер зміг оновити їх. Команда називається `collectstatic`. + +Почніть з активації вашого віртуального середовища, якщо воно все ще не активне після поперендіх кроків (PythonAnywhere використовує для цього команду під назвою `workon`, вона схожа на команду `source myenv/bin/activate`, яку Ви використовуєте на власному комп'ютері): + +{% filename %}командний рядок PythonAnywhere{% endfilename %} + + $ workon .pythonanywhere.com + (ola.pythonanywhere.com)$ python manage.py collectstatic + [...] + + +Команда `manage.py collectstatic` трохи схожа на `manage.py migrate`. Ми внесемо деякі зміни до нашого коду, а потім наказуємо Django *застосувати* ці зміни або до колекції статичних файлів сервера, або до бази даних. -* Нарешті, перейдіть на [вкладку Web](https://www.pythonanywhere.com/web_app_setup/) і натисніть **Reload**. +У будь-якому випадку, тепер ми готові перейти до ["Веб"сторінки](https://www.pythonanywhere.com/web_app_setup/) (потрібно клікнути на кнопку меню у верхньому правому куті консолі) і обрати **Перезавантажити** і нарешті перегляньте сторінку https://subdomain.pythonanywhere.com, щоб побачити результат. -І це все! Вітання :) +На цьому все! Вітаємо! :) \ No newline at end of file diff --git a/uk/how_the_internet_works/README.md b/uk/how_the_internet_works/README.md index 61cc68f8363..4dc08264460 100644 --- a/uk/how_the_internet_works/README.md +++ b/uk/how_the_internet_works/README.md @@ -1,48 +1,47 @@ # Як працює Інтернет -> На створення цього розділу нас надихнула розмова "Як працює Інтернет" Джесіки Маккеллар (http://web.mit.edu/jesstess/www/). +> Для читачів вдома: відеоверсія цього розділу - [Як працює Інтернет](https://www.youtube.com/watch?v=oM9yAA09wdc) (англ.). +> +> На створення цього розділу нас надихнув виступ Джесіки Маккеллар "Як працює інтернет" (http://web.mit.edu/jesstess/www/). -Б'ємось об заклад, ви використовуєте Інтернет кожного дня. Однак, чи знаєте ви насправді, що трапляється, коли ви набираєте адресу на зразок https://djangogirls.org у браузері та натискаєте `enter`? +Б'ємось об заклад, ви використовуєте Інтернет кожного дня. Однак, чи знаєте ви насправді, що трапляється, коли ви набираєте адресу на зразок https://djangogirls.org у вашому браузері та натискаєте `enter`? -Перша річ, яку вам необхідно зрозуміти - це те, що веб-сайт є лише набором файлів на жорсткому диску. Просто як фільми, музика або зображення. -Проте, є одна унікальна річ для веб-сайтів: вони містять комп'ютерний код, що називається HTML. +Перша річ, яку вам необхідно зрозуміти, - це те, що вебсайт є лише набором файлів на жорсткому диску. Просто як фільми, музика або зображення. Проте, є одна унікальна річ для вебсайтів: вони містять комп'ютерний код, що називається HTML. -Якщо ви не знайомі із програмуванням, спочатку може бути складно зрозуміти, що таке HTML, але веб-браузери (такі як Chrome, Safari, Firefox тощо) його люблять. -Веб-браузери розроблені спеціально, щоб розуміти цей код, виконувати його інструкції та показувати файли, з якого складається ваш сайт, саме так, як ви того забажаєте. +Якщо ви не знайомі із програмуванням, спочатку може бути складно вловити що таке HTML, але ваші веббраузери (такі як Chrome, Safari, Firefox тощо) люблять це. Веббраузери розроблені спеціально, щоб розуміти цей код, виконувати його інструкції та показувати файли, з яких складається ваш сайт, і саме так, як ви цього хочете. -Як і звичайні файли, нам потрібно зберігати HTML-файли в певному місці на жорсткому диску. В Інтернеті ми використовуємо спеціальні потужні комп'ютери, що називаються *серверами*. -Вони не мають екрану, мишки чи клавіатури, тому що їхня основна ціль - зберігати і обробляти дані. Саме тому ці комп'ютери назвали *серверами*, вони обробляють (англ. to *serve* - обробляти) ваші дані. +Як і звичайні файли, нам потрібно зберігати HTML-файли в певному місці на жорсткому диску. В інтернеті ми використовуємо спеціальні потужні комп'ютери, що називаються *серверами*. Вони не мають екрану, мишки чи клавіатури, тому що їхня основна ціль - зберігати і видавати дані. Саме тому ці комп'ютери назвали *серверами*: вони видають, можна навіть сказати «подають» (англ. to *serve* - подавати) ваші дані. -Гаразд, але ж ви хочете дізнатися як виглядає Інтернет, чи не так? +Гаразд, але ж ви хочете дізнатися як виглядає інтернет, чи не так? -Ми намалювали для вас картинку! Вона виглядає наступним чином: +Ми намалювали для вас картинку! Ось таку: -![Рисунок 1.1](images/internet_1.png) +![Figure 1.1](images/internet_1.png) -Суцільний безлад, правильно? Фактично, це мережа з'єднаних машин (вище зазначених *серверів*). Сотні тисяч машин! Багато-багато кілометрів кабелю по усьому світу! Можете відвідати веб-сайт Submarine Cable Map (http://submarinecablemap.com/), щоб побачити, наскільки складною є мережа. Тут наведено знімок з веб-сайту: +Суцільний безлад, правильно? Фактично, це мережа з'єднаних машин (вище зазначених *серверів*). Сотень тисяч машин! Багато-багато кілометрів кабелю по усьому світу! Можете відвідати вебсайт Submarine Cable Map (http://submarinecablemap.com/), щоб побачити, наскільки складною є мережа. Тут наведено знімок з вебсайту: -![Рисунок 1.2](images/internet_3.png) +![Figure 1.2](images/internet_3.png) -Вражаюче, чи не так? Але однозначно, неможливо мати проводи між кожною машиною, підключеною до Інтернету. Отже, щоб досягти машини (наприклад, ту на якій збережено https://djangogirls.org), ми повинні передати запит через багато-багато різних машин. +Вражаюче, чи не так? Але ж неможливо протягнути проводи між кожною парою машин, що під'єднані до інтернету. Отже, щоб досягти машини (наприклад тієї, на якій знаходиться https://djangogirls.org), ми повинні передати запит через багато-багато різних машин. Це виглядатиме так: -![Рисунок 1.3](images/internet_2.png) +![Figure 1.3](images/internet_2.png) -Уявіть, що коли ви набираєте https://djangogirls.org, ви відправляєте листа, що говорить: "Шановні Django Girls, я хочу побачити веб-сайт djangogirls.org. Відправте мені його, будь ласка!" +Уявіть, що коли ви набираєте https://djangogirls.org, ви відправляєте листа, в якому пишете: "Шановні Django Girls, я хочу побачити вебсайт djangogirls.org. Відправте мені його, будь ласка!" -Ваш лист надійде до найближчого поштового віділення. Далі він надходить до іншого, що знаходиться трохи ближче до вашого адресата, далі до іншого і так далі, поки не буде досягнуто остаточного пункту призначення. Єдина відмінність в тому, що при відправці багатьох листів (*пакетів даних*) в однакове місце, кожен з них може піти через абсолютно різні поштові відділення (*маршрутизатори*). Це залежить від того, як їх розподілили в кожному відділенні. +Ваш лист надійде до найближчого поштового відділення. Далі він надійде до іншого відділення, що знаходиться трохи ближче до вашого адресата, далі до іншого і так далі, поки не буде досягнуто остаточного пункту призначення. Єдина відмінність в тому, що якщо ви відправите багато листів (*пакетів даних*) в одне місце, кожен з них може піти через абсолютно різні поштові відділення (*маршрутизатори*). Це залежить від того, як їх розподілили в кожному відділенні. -![Рисунок 1.4](images/internet_4.png) +![Figure 1.4](images/internet_4.png) -Так, це так само просто. Ви відправляєте повідомлення і очікуєте певної відповіді. Звісно, замість паперу і ручки ви використовуєте байти даних, але ідея та сама! +Інтернет працює так само. Ви відправляєте повідомлення і очікуєте певної відповіді. Звісно, замість паперу і ручки ви використовуєте байти даних, але ідея та сама! -Замість адрес із назвами вулиці, міста, індексом і назвою країни, ми використовуємо IP адреси. Ваш комп'ютер спочатку запитує про DNS (англ. Domain Name System - система доменних імен) для переводу djangogirls.org в IP-адресу. Це працює подібно до старомодних телефонних довідників, де ви могли б знайти ім'я особи, з якою бажаєте зв'язатися і знайти її номер телефону та адресу. +Замість адрес із назвами вулиці, міста, індексом і назвою країни, ми використовуємо IP-адреси. Ваш комп'ютер спочатку запитує DNS-сервер (англ. Domain Name System - Система доменних імен) для "перекладу" імені djangogirls.org на IP-адресу. Це працює трохи подібно до старомодних телефонних довідників, де ви могли б знайти ім'я особи, з якою бажаєте зв'язатися, і отримати там номер її телефону та адресу. -Коли ви відправляєте листа, це потребує наявності певних речей для коректної доставки: адреса, штамп тощо. Також ви використовуєте мову, котру розуміє отримувач, правда ж? Те ж саме стосується і *пакетів даних*, які ви відправляєте, щоб побачити веб-сайт. Ми використовуємо протокол, який називається HTTP (англ. Hypertext Transfer Protocol, протокол передачі гіпер-текстових документів). +Коли ви відправляєте звичайного листа, це потребує наявності певних атрибутів для коректної доставки: адреса, штамп тощо. Також ви використовуєте мову, яку розуміє отримувач, правда ж? Те ж саме стосується і *пакетів даних*, які ви відправляєте, щоб побачити вебсайт. Ми використовуємо протокол, який називається HTTP (англ. HyperText Transfer Protocol - протокол передачі гіпертекстових документів). -Отже, по суті, коли у вас є веб-сайт, вам треба мати *сервер* (машину), де він житиме. Коли *сервер* отримує вхідний *запит* (в листі), він відправляє назад ваш веб-сайт (в іншому листі). +Отже, по суті, коли у вас є вебсайт, вам треба мати *сервер* (машину), де він житиме. Коли *сервер* отримує вхідний *запит* (у листі), він відправляє назад ваш вебсайт (в іншому листі). -Оскільки ви читаєте навчальний посібник з Django, ви запитаєте, що ж робить Django. Коли ви відправляєте відповідь, то не завжди бажаєте відправляти одне й те саме кожному. Набагато краще, якщо ваші листи є персоналізованими, особливо для осіб, які щойно вам написали, еге ж? Django допомагає вам зі створенням цих персоналізованих цікавих листів :). +Оскільки це є навчальний посібник з Django, ви можете запитати, що ж саме робить Django. Коли ви відправляєте відповідь, то не завжди бажаєте відправляти одне й те саме кожному. Набагато краще, якщо ваші листи будуть персоналізованими, особливо для тих, хто вам щойно написав, правда ж? Django допомагає вам зі створенням цих персоналізованих, цікавих листів. :) -Досить розмов, час творити! +Досить говорити - час творити! \ No newline at end of file diff --git a/uk/html/README.md b/uk/html/README.md index ab871101e16..0b4a13b38f2 100644 --- a/uk/html/README.md +++ b/uk/html/README.md @@ -2,15 +2,15 @@ Ви можете запитати, що таке шаблон? -Шаблон - це файл, який ми можемо повторно використовувати для представлення різноманітної інформації в послідовному форматі. Наприклад, ви можете використовувати шаблон для допомоги у написанні листа, бо, хоча кожен лист може містити різне повідомлення та бути адресованим різним особам, усі листи поширюватимуться у однаковому форматі. +Шаблон – це файл, який ми можемо повторно використовувати для представлення різної інформації в послідовному форматі – наприклад, Ви можете використовувати шаблон, для допомоги у написанні листа, оскільки, хоча кожен лист може містити різні повідомлення та бути адресованим іншій особі, всі повідомлення матимуть однаковий формат. -Формат Django шаблону описаний мовою, що називається HTML (це HTML, зазначений у першому розділі **Як працює Інтернет**). +Формат шаблону Django описується мовою HTML (це HTML, про який ми згадували в першому розділі **Як працює Інтернет**). ## Що таке HTML? -HTML - це простий код, що інтерпретується вашим веб браузером (таким як Chrome, Firefox чи Safari) для відображення веб сторінки для користувача. +HTML – це код, який інтерпретується Вашим веббраузером, таким як Chrome, Firefox або Safari, для відображення вебсторінки для користувача. -HTML розшифровується як "Мова розмітки гіпертексту". __Гіпертекст__ означає тип тексту, який підтримує гіперпосилання між сторінками. __Розмітка__ (англ. markup) означає, що ми отримали документ із розміченим кодом для того, щоб повідомити комусь (у даному випадку, браузеру) як треба інтерпретувати сторінку. HTML код побудований за допомогою __тегів__, кожен з яких починається із `<` і закінчується на `>`. Теги представляють __елементи розмітки__. +HTML розшифровується як "Мова розмітки гіпертексту". **Гіпертекст** означає тип тексту, який підтримує гіперпосилання між сторінками. **Markup** (розмітка) означає, що ми отримали документ із розміченим кодом для того, щоб повідомити дещо (у даному випадку, браузер) як треба інтерпретувати сторінку. HTML код побудований за допомогою **тегів**, кожен з яких починається із `<` і закінчується `>`. Теги представляють **елементи розмітки**. ## Ваш перший шаблон! @@ -21,50 +21,59 @@ HTML розшифровується як "Мова розмітки гіперт blog └───templates └───blog + -(Вас може здивувати, для чого нам потрібно дві папки із однаковим ім'ям `blog` - як виявиться пізніше, це всього лише зручне узгодженість із найменування, котра спрощує життя, коли речі починають ускладнюватися.) +(У Вас може виникнути питання, навіщо нам потрібні два каталоги, які називаються `blog` – Ви пізніше дізнаєтеся, що це зручне узгодження імен, яке полегшує життя, коли все ускладнюється.) -А тепер створіть файл `post_list.html` (просто залиште його поки що порожнім) всередині папки `blog/templates/blog`. +А тепер створіть файл `post_list.html` (просто залиште його поки що пустим) всередині папки `blog/templates/blog`. -Погляньте, як тепер виглядає ваш веб сайт: http://127.0.0.1:8000/ +Погляньте як тепер виглядає ваш веб сайт: http://127.0.0.1:8000/ -> Якщо помилка `TemplateDoesNotExists` досі не зникла, спробуйте перезапустити ваш сервер. Перейдіть до командного рядка, зупиніть сервер, натиснувши Ctrl+C (клавіші Control і C разом) та активуйте його знову, запустивши команду `python manage.py runserver`. +> Якщо у Вас все ще не зникає помилка `TemplateDoesNotExist`, спробуйте перезапустити сервер. Перейдіть до командного рядка, зупиніть сервер, натиснувши Ctrl+C (клавіші Control і C разом) і запустіть його знову, виконавши команду `python manage.py runserver`. ![Рисунок 11.1](images/step1.png) -Більше ніяких помилок! Вітання :) Однак, ваш сайт насправді не публікує нічого, окрім пустої сторінки, оскільки ваш шаблон також пустий. Ми маємо це виправити. +Помилки більше немає! Вітання! :) Однак,  Ваш вебсайт насправді не публікує нічого, крім порожньої сторінки, оскільки ваш шаблон також порожній. Нам потрібно це виправити.  -Додайте наступне у ваш файл шаблону: +Відкрийте новий файл у редакторі коду та додайте наступне: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html +

Hi there!

It works!

+ ``` -То як тепер виглядає ваш веб-сайт? Натисніть, щоб з'ясувати: http://127.0.0.1:8000/ +То як тепер виглядає Ваш сайт? Перейдіть за посиланням, щоб дізнатися: http://127.0.0.1:8000/ ![Рисунок 11.2](images/step3.png) -Спрацювало! Гарна робота :) +Спрацювало. Гарна робота! :) + +* Рядок `` не є тегом HTML. Він лише показує тип документа. Тут він показує браузеру, що тип документа [HTML5](https://html.spec.whatwg.org/#the-doctype). Так завжди починається будь-який файл HTML5. +* Найпростіший тег `` завжди є початком будь-якої html сторінки, а `` завжди є кінцем. Як бачите, весь контент вебсайту розміщений між початковим тегом `` і закриваючим тегом `` +* `

` — тег для елементів абзацу; `

` закриває кожен абзац -- Базовий тег `` завжди є початком будь-якої веб сторінки і `` - завжди є кінцем. Як бачите, увесь контент сайту розміщений між початковим тегом `` і закриваючим тегом ``. -- `

` - тег для елементів абзацу; `

` закриває кожен абзац. +## Заголовок та тіло документу HTML -## Голова і тіло (Head & body) +Кожну сторінку HTML також можна поділити на два елементи: **head** - (голова) і **body** - (тіло. -Кожну сторінку HTML також можна поділити на два елементи: __head__ - (голова) і __body__ - (тіло). +* **head** - елемент, що містить інформацію про документ, яка не відображається на екрані. -- __head__ - елемент, що містить інформацію про документ, яка не відображається на екрані. +* **body** - елемент, що містить усе інше, що відображається як частина веб сторінки. -- __body__ - елемент, що містить усе інше, що відображається як частина веб сторінки. +Ми використовуємо `` щоб повідомити браузер про конфігурацію сторінки, а `` щоб повідомити браузер, що у дійсності знаходиться на сторінці. -Ми використовуємо `` щоб повідомити браузер про конфігурацію сторінки, а ``, щоб повідомити браузер, що у дійсності знаходиться на сторінці. +Наприклад, Ви можете помістити елемент заголовка вебсторінки всередині ``, якщо виконаєте наступні дії: -Наприклад, ви можете розмістити заголовок веб-сторінки всередині `` наступним чином: +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html + Ola's blog @@ -80,115 +89,138 @@ HTML розшифровується як "Мова розмітки гіперт ![Рисунок 11.3](images/step4.png) -Зауважте, як браузер зрозумів , що "Ola's blog" - це заголовок вашої сторінки? Він інтерпретував `Ola's blog` і розмістив текст у рядку заголовка вашого браузера (він також буде використаний для закладок чи інших речей). +Зауважте як браузер зрозумів , що "Ola's blog" це заголовок вашої сторінки? Він інтерпретував `Ola's blog` і розмістив текст у рядку заголовка вашого браузера (він також буде використаний для закладок чи інших речей). -Можливо, ви також звернули увагу, що кожен відкриваючий тег відповідає *закриваючому тегу*, із `/`, і ці елементи є *вкладеними* (тобто ви не можете закрити окремий тег поки усі теги, що містяться всередині не будуть також закриті). +Можливо, ви також зауважили, що кожен відкриваючий тег відповідає *закриваючому тегу*, із `/`, і ці елементи є *вкладеними* (тобто ви не можете закрити окремий тег поки усі теги, що містяться всередині не будуть також закриті). Це щось на кшталт як покласти речі всередину ящиків. У вас є один великий ящик, ``; всередині цього ящика є ``, що містить ще менші ящики: `

`. -Ви повинні керуватися цими правилами _закриваючих_ тегів, і _вкладених_ елементів - якщо ви цього не робитимите, браузер може бути не в змозі інтерпретувати їх правильно і ваша сторінка буде відображатись некоректно. +Ви повинні керуватися цими правилами працюючи з тегами *закривання* та *вкладених* елементів – якщо Ви цього не зробите, браузер не зможе правильно їх інтерпретувати, і Ваша сторінка буде відображатися неправильно. ## Налаштуйте ваш шаблон А тепер можете трохи побавитися і спробувати налаштувати ваш шаблон! Тут наведено декілька корисних тегів для цього: -- `

Заголовок

` - для найважливішого заголовка -- `

Підзаголовок

` для заголовків наступного рівня -- `

Підпідзаголовок

` ... і так далі, аж до `
` -- `текст` робить акцент на вашому тексті -- `текст` робить сильний акцент на вашому тексті -- `
` переходить на наступну лінію (ви не можете нічого розмістити всередині br) -- `link` створює посилання -- `
  • перший елемент
  • другий елемент
` створює список, такий як цей! -- `
` визначає блок сторінки - -Тут наведено повний приклад шаблону: +* `

Заголовок

` для Вашого найважливішого заголовка +* `

Підзаголовок

` для заголовків наступного рівня +* `

Підзаголовок

` …і так далі, аж до `
` +* `

Абзац тексту

` +* `текст` робить акцент на вашому тексті +* `текст` робить сильний акцент на вашому тексті +* `
` переходить до іншого рядка (Ви не можете помістити нічого всередині br і там такж немає закривального тегу) +* `link` створює посилання +* `
  • перший елемент
  • другий елемент
` створює список, такий як цей! +* `
` визначає блок сторінки +* `` визначає набір навігаційних посилань +* `
` визначає незалежний, автономний контент +* `
` визначає розділ в документі +* `
` визначає заголовок документа або розділу +* `
` визначає основний контент документа +* `` визначає деякий контент, крім того, в якому він розміщений (наприклад, бічна панель) +* `
` визначає нижній колонтитул для документа або розділу +* `` визначає конкретний час (або дату) + +Ось приклад повного шаблону, скопіюйте та вставте його в `blog/templates/blog/post_list.html`: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html + Django Girls blog - +
+

Django Girls Blog

+
-
-

published: 14.06.2014, 12:14

+
+

My first post

Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus.

-
+ -
-

published: 14.06.2014, 12:14

+
+

My second post

Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut f.

-
+ ``` -Тут було створено три блоки `div`. +Тут ми створили один розділ `заголовоку` і два розділи ` статті`. -- Перший `div` елемент містить заголовок нашого блогу - а точніше, заголовок і посилання -- Два інших `div` елементи містять наші пости із датою публікації, `h2` із заголовком поста, який можна клікнути і два `p` (абзаци) тексту, один для дати, а інший для нашого блог посту. +* Елемент `заголовок` містить назву нашого блогу – а точніше, заголовок і посилання +* Два елементи `статті` містять наші дописи в блозі з датою публікації в елементі `час`, елемент `h2` із назвою публікації, на який можна клікнути, і елемент `p` (абзац) для тексту нашого посту в блозі. Отримуємо наступний ефект: ![Рисунок 11.4](images/step6.png) -Йой! Але досі, наш шаблон лише незмінно відображає точно __таку ж інформацію__ - тоді як раніше йшлося про шаблони, що дозволяють нам відображувати __різну__ інформацію в __однаковому форматі__. +Йой! Але поки що наш шаблон завжди відображає лише **одну й ту саму інформацію**, тоді як раніше ми говорили про шаблони, які дозволяють нам відображати **іншу** інформацію в **тому ж форматі< /0>.

-Що б ми дійсно хотіли зробити, так це відобразити реальні пости, додані в нашій панелі адміністратора Django - це те, до чого ми перейдемо далі. +Те, що ми б хотіли зробити, це відобразити реальні пости, додані в панелі адміністратора Django – це те, що ми розглядатимемо далі. ## Ще одна річ: розгортання! Було б добре побачити все це в Інтернеті, правда? Давайте зробимо ще одне розгортання на PythonAnywhere: -### Фіксування (commit) і завантаження (push) коду на GitHub +### Зафіксуйте та завантажте свій код на GitHub -По-перше, давайте подивимося, які файли були змінені після розгортання (виконайте ці команди локально, не на PythonAnywhere): +По-перше, давайте подивимося які файли були змінені після розгортання (виконайте ці команди локально, не на PythonAnywhere): + +{% filename %}command-line{% endfilename %} $ git status + -Переконайтеся, що ви перебуваєте в директорії `djangogirls`, далі давайте скажемо для `git` включити всі зміни в рамках цього каталогу: +Переконайтеся, що ви перебуваєте в каталозі `djangogirls` , далі давайте скажемо `git` включити всі зміни в цей каталог: - $ git add --all . +{% filename %}command-line{% endfilename %} -> __Зауваження__ `-A` (коротко усі - "all") означає, що `git` також розпізнає якщо раптом ви видалили файли (за замовчуванням, він розпізнає лише нові/змінені файли). Також пам'ятайте (з розділу 3), що `.` означає поточну директорію. + $ git add . + Перед тим як завантажити усі файли, давайте перевіримо що ж буде завантажувати `git` (усі файли, які буде завантажувати `git` повинні тепер з'явитися і бути позначеними зеленим кольором): +{% filename %}command-line{% endfilename %} + $ git status + Майже на місці, а тепер час повідомити йому про те, що треба зберегти ці зміни в його історії. Ми збираємося задати "commit message" що ж ми змінили. На цьому етапі можна набрати будь-що, що вважатимете за потрібне, однак, має сенс надрукувати щось дійсно зрозуміле, щоб, таким чином, ви могли згадати що ви зробили у майбутньому. +{% filename %}command-line{% endfilename %} + $ git commit -m "Changed the HTML for the site." + -> __Зауваження__ Переконайтеся, що ви використали подвійні лапки навколо повідомлення про здійснену фіксацію. +> **Зверніть увагу** Переконайтеся, що Ви взяли повідомлення про здіснену фіксацію в подвійні лапки. -Після того, як ми це зробили, завантажимо (push) наші зміни до GitHub: +Після того, як це зробили, потрібно завантажити (push) наші зміни на GitHub: - git push +{% filename %}command-line{% endfilename %} + $ git push + ### Завантаження (pull) нового коду на PythonAnywhere і перезапуск веб-додатку * Відкрийте [сторінку з терміналами на PythonAnywhere](https://www.pythonanywhere.com/consoles/) і переключіться на вже запущений **Bash термінал** (або запустіть новий). Далі, наберіть команди: -``` -$ cd ~/my-first-blog -$ source myvenv/bin/activate -(myvenv)$ git pull -[...] -(myvenv)$ python manage.py collectstatic -[...] -``` +{% filename %}PythonAnywhere command-line{% endfilename %} + + $ cd ~/.pythonanywhere.com + $ git pull + [...] + -Подивіться, що ваш код почав завантажуватись. Якщо ви хочете перевірити успішність процедури, відкрийте вкладку **Files** і подивіться на свій код на PythonAnywhere. +Вам потрібно буде замінити `` своїм фактичним субдоменом PythonAnywhere без кутових дужок. Ім’я вашого субдомену зазвичай — це, як правило, Ваше ім’я користувача PythonAnywhere, але в деяких випадках воно може бути дещо іншим (наприклад, якщо Ваше ім’я користувача містить великі літери).  Отже, якщо ця команда не працює, скористайтеся командою `ls` (список файлів), щоб знайти своє фактичне ім’я субдомену/папки, а потім `cd`. +Тепер дивіться, як завантажується ваш код. Якщо Ви хочете перевірити, чи він надійшов, Ви можете перейти на **сторінку "Файли"** і переглянути свій код на PythonAnywhere (Ви можете перейти на інші сторінки PythonAnywhere за допомогою кнопки меню на сторінці консолі). -* Зрештою, переключіться на вкладку [Web](https://www.pythonanywhere.com/web_app_setup/) і натисніть **Reload**. +* А тепер перейдіть на ["Веб"сторінку](https://www.pythonanywhere.com/web_app_setup/) і натисніть **Перезавантажити** у вебпрограмі. -Оновлення повинні відобразитись на вашому веб-сайті! Переключись на нього і онови сторінку. Ви повинні побачити зміни :) +Ваше оновлення повинно сапрацювати! Перейдіть і оновіть свій вебсайт у браузері. Зміни повинні бути помітні. :) \ No newline at end of file diff --git a/uk/installation/README.md b/uk/installation/README.md index bff76bf0fef..0901e8c27dc 100644 --- a/uk/installation/README.md +++ b/uk/installation/README.md @@ -1,48 +1,68 @@ -# Якщо ви проходите цей підручник вдома +# Якщо ви опрацьовуєте цей підручник вдома -Якщо ви проходите цей посібник вдома, а не на одному з [майстер-класів Django Girls](https://djangogirls.org/events/), ви можете повністю пропустити цей розділ і перейти до розділу [Як працює Інтернет](../how_the_internet_works/README.md). +Якщо ви опрацьовуєте підручник вдома, а не на одному з [заходів Django Girls](https://djangogirls.org/events/), ви можете повністю пропустити цей розділ зараз і перейти безпосередньо до розділу [Як працює Інтернет](../how_the_internet_works/README.md). -Справа в тому, що ми все одно розглядаємо ці речі в посібнику, а цей розділ - лише додаткова сторінка, де зібрані разом всі інструкції по встановленню. Зустріч Django Girls включає в себе "Вечір налаштувань", коли ми встановлюємо все потрібне, щоб не витрачати на це час під час воркшопу, це дуже зручно для нас. - -Якщо ви вважаєте це корисним, можете пройти цей розділ також. Але якщо бажаєте почати вчитися без встановлення купи речей на ваш комп'ютер, пропустіть цей розділ і ми пояснимо як ставити програми пізніше. +Ця сторінка є лише додатковою - на ній ми зібрали інструкції зі встановлення всіх програм, які потрібні протягом курсу (така підбірка є корисною для деяких форматів семінару). Ви можете одразу встановити все, що є на цій сторінці. Але якщо бажаєте почати вчитися без встановлення купи речей на ваш комп'ютер, пропустіть цей розділ, а ми пояснимо, як ставити програми, пізніше . Успіхів! +# Якщо ви плануєте відвідати семінар + +Якщо Ви плануєте відвідати один із [заходів Django Girls](https://djangogirls.org/events/): + +* У вашому семінарі може відбутися «установка» перед початком головного семінару. Якщо Ви знаходитесь на сайті для встановлення, ця сторінка для вас! Дотримуйтесь інструкцій, щоб встановити все необхідне для семінару, зверніться за допомогою до тренерів, якщо буде потрібно, Тоді під час основного семінару ви зможете пропустити інструкції зі встановлення, з якими ви зіткнетеся в основному підручнику, коли почнете їх вивчення. +* Організатори Вашого семінару, можливо, просили Вас спробувати вдома встановити все на свій комп’ютер перед початком семінару. Якщо вас попросили це зробити - ця сторінка саме для вас! Якомога старанніше дотримуйтесь наведених інструкцій. Якщо вам не вдалось встановити елемент, то під час семінару, коли ви перейдете до етапу вичення теми "встановлення" в основному підручнику, ви зможете отримати допомогу від свого тренера. +* Якщо ви не розглядали тему "встановлення" на семінарі (або ви не мали змоги відвідати), або якщо організатори не просили нічого встановлювати заздалегдь, пропустіть цб сторінку і переходьтк одразу до розділу [Як працює інтернет](../how_the_internet_works/README.md). Під час роботи з підручником ви встановлюватимете всі необхідні елемети. + # Встановлення -На воркшопі ви будете створювати блог, і в посібнику є кілька підготовчих задач по встановленню, які було б добре виконати заздалегідь, так щоб на воркшопі ви були відразу готові програмувати. -# Встановіть Python +У цьому підручнику ви створюватимете блог. Для того, щоб зробити це, в ході опрацювання підручника вам доведеться встановлювати різне програмне забезпечення на комп'ютер, і налаштовувати деякі облікові записи в мережі, в міру їх необхідності. На цій сторінці зібрані всі інструкції з встановлення та входу (що може бути корисним для формату семінарів) + + {% include "/chromebook_setup/instructions.md" %} + + + +# Коротко про командний рядок {#command-line} + +Багато наведених нижче кроків, які стосуються "консолі", "терміналу", "вікна команди", або "командного рядка" — означають одне й те саме: вікно на вашому комп’ютері, де можна вводити команди. Коли ви перейдете до опрацювання основного підручника, ви дізнаєтесь більше про командний рядок. Наразі, найголовніше, що вам потрібно знати, - як відкрити вікно команд і я воно виглядає: {% include "/intro_to_command_line/open_instructions.md" %} + +# Встановіть Python {#python} + {% include "/python_installation/instructions.md" %} -# Налаштуйте virtualenv та встановіть Django -{% include "/django_installation/instructions.md" %} +# Встановіть редактор коду {#code-editor} -# Встановіть редактор коду {% include "/code_editor/instructions.md" %} -# Встановіть Git +# Налаштуйте віртуальне середовище та встановіть Django {#virtualenv} + +{% include "/django_installation/instructions.md" %} + +# Встановіть Git {#git} + {% include "/deploy/install_git.md" %} -# Створіть аккаунт на GitHub -Зайдіть на [GitHub.com](https://www.github.com) і зареєструйте новий безкоштовний аккаунт користувача. +# Створіть обліковий запис GitHub {#github-account} -# Створіть аккаунт на PythonAnywhere -{% include "/deploy/signup_pythonanywhere.md" %} +Переходьте на [GitHub.com](https://www.github.com) та реєструйте новий безкоштовний обліковий запис. Будьте певні, що пам'ятаєте пароль (додавайте до свого менеджера паролів, якщо ви ним користуєтеся). +# Створіть обліковий запис PythonAnywhere {#pythonanywhere-account} -# Почніть читати +{% include "/deploy/signup_pythonanywhere.md" %} -Вітання, ви все зробили і готові йти вперед! Якщо ви все ще маєте час перед воркшопом, буде корисно, якщо ви почнете читати кілька вступних розділів: +# Почніть читати - * [Як працює Інтернет](../how_the_internet_works/README.md) +Вітаємо, все готово до роботи! Якщо у вас ще є час до семінару, було б корисно почати читати кілька вступних розділів: - * [Знайомство з командним рядком](../intro_to_command_line/README.md) +* [Як працює інтернет](../how_the_internet_works/README.md) - * [Вступ до Python](../python_introduction/README.md) +* [Знайомство з командним рядком](../intro_to_command_line/README.md) - * [Що таке Django?](../django/README.md) +* [Знайомтво з Python](../python_introduction/README.md) +* [Що таке Django?](../django/README.md) -# Насолоджуйтесь подією! +# Насолоджуйтесь семінаром! -Після початку воркшопу, можете відразу перейти до [вашого першого Django проекту!](../django_start_project/README.md), тому що ви пройшли матеріал із попередніх розділів. +Коли розпочнеться семінар, Ви зможете одразу перейти до розділу [Ваш перший проект на Django!](../django_start_project/README.md), оскільки ви вже опанували матеріал попередніх розділів. \ No newline at end of file diff --git a/uk/intro_to_command_line/README.md b/uk/intro_to_command_line/README.md index 01859a6c4e5..6ec31e1c828 100644 --- a/uk/intro_to_command_line/README.md +++ b/uk/intro_to_command_line/README.md @@ -1,254 +1,441 @@ # Вступ до інтерфейсу командного рядка -Це захоплює, чи не так?! Ви напишете свій перший рядок коду через декілька хвилин :) +> Для читачів вдома: відеоверсія цього розділу - [Ваш новий друг: командний рядок](https://www.youtube.com/watch?v=jvZLWhkzX-8) (англ.). -__Дозвольте нам представити вас вашому новому другові: командний рядок!__ +Це захоплює, так?! Ви напишете свій перший рядок коду через декілька хвилин :) -Наступні кроки покажуть вам, як користуватися чорним вікном хакерів. Спочатку це може видаватися трохи жахливим, однак насправді - це лише командна підказка, що очікує від вас певних команд. +**Дозвольте нам представити вам нового друга: командний рядок!** -> **Примітка.** Зауважте, що в цій книзі ми використовуємо терміни 'директорія', 'каталог' та 'папка' взаємозамінно, ці слова означають одне й те саме. +Наступні кроки покажуть вам, як користуватися чорним вікном, яке є інструментом усіх хакерів. Спочатку це може видаватися трохи жахливим, однак насправді це лише запрошення, що очікує певних команд від вас. + +> **Примітка.** Зауважте, що в цій книзі ми використовуємо терміни "директорія", "каталог" та "папка" взаємозамінно, ці слова означають одне й те саме. ## Що таке командний рядок? -Вікно, яке зазвичай називають __командним рядком__ або __інтерфейсом командного рядка__, є текстовою програмою для перегляду, обробки і управління файлами на вашому комп'ютері. Як Провідник на Windows чи Finder на Mac, але без графічного інтерфейсу. Інші назви командного рядка: *cmd*, *CLI*, *prompt*, *console* або *terminal*. +Вікно, яке зазвичай називають **командним рядком** або **інтерфейсом командного рядка**, є текстовою програмою для перегляду, редагування та інших операцій з файлами на вашому комп'ютері. Як Провідник на Windows чи Finder на Mac, але без графічного інтерфейсу. Інші назви командного рядка: *cmd*, *CLI*, *prompt*, *console* або *terminal*. ## Відкриваємо інтерфейс командного рядка -Щоб почати експериментувати, нам потрібно спочатку відкрити наш інтерфейс командного рядка. +Щоб почати експериментувати, нам потрібно спочатку відкрити наш командний рядок. -### Windows +{% include "/intro_to_command_line/open_instructions.md" %} -Перейдіть до меню Пуск → Усі програми → Стандартні → Командний рядок. +## Запрошення -### Mac OS X +Має з'явитися біле або чорне вікно, що очікує на ваші команди. -Додатки → Утиліти → Термінал. + -### Linux +Якщо ви працюєте на Mac або на Linux, ви напевно побачите `$`, на зразок: -Скоріш за все Додатки → Стандартні → Термінал, але це може залежати від вашої системної версії. Якщо тут його немає, просто загугліть :) +{% filename %}command-line{% endfilename %} -## Командний рядок + $ + -Має з'явитися біле або чорне вікно, що очікує на ваші команди. + -Якщо ви працюєте на Mac або на Linux, ви напевно побачите `$`, на зразок: + - $ +На Windows, це знак `>`, ось так: -На Windows, це знак `>`: +{% filename %}command-line{% endfilename %} > + + +Подивіться на секцію Linux трохи вище - ви побачите щось подібне, коли перейдете до PythonAnywhere пізніше у цьому посібнику. + + -Кожній команді буде передувати цей знак і один пробіл, але ви не мусите набирати їх. Ваш комп'ютер робитиме це для вас сам :) +Кожній команді буде передувати символ `$` або `>` і після нього один пробіл, але ви не мусите набирати їх. Ваш комп'ютер робитиме це для вас сам :) -> Просто маленьке зауваження: у вашому випадку ви побачите щось на кшталт `C:\Users\ola>` або `Olas-MacBook-Air:~ ola$` перед знаком командного рядка і це на 100% є правильним. +> Маленьке зауваження: перед знаком командного рядка ви, скоріш за все, побачите щось на зразок `C:\Users\ola>` або `Olas-MacBook-Air:~ ola$`. Це є на 100% правильним. -Частина до `$` або `>` включно називається *запрошенням командного рядка* або скорочено *командним рядком*. Вона запрошує вас ввести туди щось. +Весь цей текст включно зі знаком `$` або `>` називається *запрошенням командного рядка* або скорочено *запрошенням*. Він запрошує вас ввести туди щось. -У посібнику, коли нам потрібно, щоб ви набрали щось в командний рядок, ми включатимемо `$` або `>`, а іноді й більше символів зліва. Ви можете ігнорувати ліву частину і друкувати в командний рядок лише те, що починається після `$`. +У посібнику, коли нам потрібно, щоб ви набрали щось у командному рядку, ми включатимемо `$` або `>`, а іноді й більше символів зліва. Ігноруйте ліву частину і набирайте лише команду, яка починається після знаку запрошення. ## Ваша перша команда (ЙОЙ!) Почнемо з чогось простенького. Наберіть команду: + + +{% filename %}command-line{% endfilename %} + $ whoami + + + -або + + +{% filename %}command-line{% endfilename %} > whoami + + + + +Далі натисніть `Enter`. Це наш результат: -Далі натисніть `enter`. Це наш результат: +{% filename %}command-line{% endfilename %} $ whoami olasitarska + -Як бачимо, комп'ютер лише виводить ваше ім'я користувача. Файно, еге ж?:) +Як бачимо, комп'ютер виводить ваше ім'я користувача. Файно, еге ж?:) -> Спробуйте набирати кожну команду, а не копіювати і вставляти. Таким чином ви більше запам'ятаєте! +> Спробуйте набирати кожну команду, а не копіювати і вставляти. Таким чином, ви більше запам'ятаєте! ## Основи -У кожної операційної системи є трохи відмінні набори команд для командного рядку, отже, будьте певними, що виконуєте інструкції саме для вашої операційної системи. Давайте спробуємо? +У кожної операційної системи є трохи відмінні набори команд для командного рядка, отже будьте певними, що виконуєте інструкції саме для вашої операційної системи. Давайте спробуємо? ### Поточна директорія -Було б чудово знати, де ми перебуваємо зараз, чи не так? Давайте подивимося. Введіть цю команду і натисніть `enter`: +Було б приємно знати, де ми перебуваємо зараз, чи не так? Давайте подивимося. Введіть цю команду і натисніть `Enter`: + + + +{% filename %}command-line{% endfilename %} $ pwd /Users/olasitarska + + +> Примітка: "pwd" розшифровується як "print working directory" (англ. "надрукувати робочу папку"). -Якщо ви працюєте на Windows: + + + + +{% filename %}command-line{% endfilename %} > cd C:\Users\olasitarska + + +> Примітка: "cd" означає "'change directory". Проте у PowerShell ви можете використовувати pwd - так же само, як на Linux або Mac OS X. -Можливо, ви побачите щось схоже на вашій машині. Після того, як ви відкрили командний рядок, ви зазвичай починаєте зі своєї домашньої папки. + -> Зауваження: 'pwd' відповідає 'print working directory' (англ. надрукувати робочу папку). +Можливо, ви побачите щось таке на вашій машині. Після того, як ви відкрили командний рядок, ви зазвичай починаєте зі своєї домашньої папки. + +* * * ---- +### Довідка для команд + +Багато команд, які можна вводити у командному рядку, мають вбудовану довідку, яку ви можете відобразити та прочитати! Наприклад, дізнайтесь більше про команду поточної директорії: + + + +ОС X та Linux мають команду `man` , що видає вам довідку по іншим командам. Спробуйте `man pwd` і подивіться, що вона видає, або помістіть `man` перед іншими командами, щоб побачити їхню довідку. Результат `man` зазвичай розбито на сторінки. Використовуйте пробіл, щоб перейти на наступну сторінку, і `q` , щоб вийти з перегляду довідки. + + + + + +Додавання суфікса `/?` до більшості команд відобразить сторінку довідки. Можливо, доведеться прокрутити командне вікно, щоб побачити його повністю. Спробуйте `cd /?`. + + ### Список файлів і папок Отже, що ж всередині? Було б круто з'ясувати. Давайте подивимось: + + +{% filename %}command-line{% endfilename %} + $ ls Applications Desktop Downloads Music ... + + + + + -Windows: +{% filename %}command-line{% endfilename %} > dir Directory of C:\Users\olasitarska - 05/08/2014 07:28 PM Applications - 05/08/2014 07:28 PM Desktop - 05/08/2014 07:28 PM Downloads - 05/08/2014 07:28 PM Music + 05/08/2020 07:28 PM Applications + 05/08/2020 07:28 PM Desktop + 05/08/2020 07:28 PM Downloads + 05/08/2020 07:28 PM Music ... + ---- +> Примітка: у PowerShell ви можете використовувати 'ls', як у Linux або Mac OS X. + +* * * ### Змінити поточну директорію -Тепер давайте перейдемо до директорії робочого столу: +Тепер давайте перейдемо до директорії Робочого столу: + + + +{% filename %}command-line{% endfilename %} $ cd Desktop + + + + + + +{% filename %}command-line{% endfilename %} + + $ cd Desktop + + +Зверніть увагу, що назва каталогу "Desktop" може бути перекладена на мову вашого облікового запису Linux. У такому випадку вам треба замінити `Desktop` на назву перекладу; наприклад, `Робочий стіл` для української. + + -Windows: + + +{% filename %}command-line{% endfilename %} > cd Desktop + + + Перевірте, чи дійсно щось змінилось: + + +{% filename %}command-line{% endfilename %} + $ pwd /Users/olasitarska/Desktop + + + + + -Windows: +{% filename %}command-line{% endfilename %} > cd C:\Users\olasitarska\Desktop + -Ось! + -> ПРОФІ хитрощі: якщо ви наберете `cd D` і потім натиснете `tab` на клавіатурі, командний рядок автоматично заповнить решту імені, таким чином можна переходити швидше. Якщо папок, що починаються з "D" більше однієї, натисніть кнопку `tab` двічі для отримання списку варіантів. +Так, ось воно! + +> ПРОФІ хитрощі: якщо ви наберете `cd D` і потім натиснете `Tab` на клавіатурі, командний рядок автоматично заповнить решту імені, таким чином можна набирати команди швидше. Якщо папок, що починаються з "D", більше однієї, натисніть клавішу `Tab` двічі, щоб отримати список варіантів. * * * -### Створити директорію +### Створити директорію + +Як щодо створення каталогу practice на вашому робочому столі? Ви можете зробити це таким чином: + + -Як щодо створення каталогу `practice` на вашому робочому столі? Ви можете зробити це таким чином: +{% filename %}command-line{% endfilename %} $ mkdir practice + + + + + -Windows: +{% filename %}command-line{% endfilename %} > mkdir practice + -Ця коротка команда створить папку з іменем `practice` на вашому робочому столі. Може перевірити чи є вона там, просто глянувши на свій Робочий стіл або запустивши команду `ls` або `dir`! Спробуйте :) + -> ПРОФІ хитрощі: Якщо ви не хочете кожного разу набирати одну й ту ж команду, спробуйте натиснути кнопки `стрілка вгору` та `стрілка вниз` на своїй клавіатурі щоб повторити нещодавно використовувані команди. +Ця коротка команда створить папку з іменем `practice` на вашому Робочому столі. Можете перевірити, чи з'явилась вона там, просто глянувши на свій Робочий стіл або запустивши команду `ls` або `dir`! Спробуйте :) ---- +> ПРОФІ хитрощі: Якщо ви не хочете кожного разу набирати одну й ту ж команду, спробуйте натиснути клавіші `Стрілка вгору` та `Стрілка вниз` на своїй клавіатурі, щоб повторити нещодавно використані команди. + +* * * ### Вправа! -Невеличке випробування для вас: в щойно створеній директорії `practice` створіть папку `test`. Використайте команди `cd` та `mkdir`. +Невеличке випробування для вас: у щойно створеній директорії `practice` створіть папку `test`. Використайте для цього команди `cd` та `mkdir`. + +#### Розв'язок: -#### Розв'язання: + + +{% filename %}command-line{% endfilename %} $ cd practice $ mkdir test $ ls test + + + + + -Windows: +{% filename %}command-line{% endfilename %} > cd practice > mkdir test > dir - 05/08/2014 07:28 PM test + 05/08/2020 07:28 PM test + + + Вітаємо! :) ---- +* * * ### Прибираємо -Ми не хочемо залишити безлад, то ж давайте видалимо усе, що ми створили до цього моменту. +Ми не хочемо залишити безлад, тож давайте видалимо усе, що ми створили до цього моменту. Спочатку нам потрібно повернутися назад до директорії Робочий стіл: + + +{% filename %}command-line{% endfilename %} + $ cd .. + + + -Windows: + + +{% filename %}command-line{% endfilename %} > cd .. + + + + +Використання `cd` із `..` змінить вашу поточну директорію на батьківську (тобто папку, що містить вашу поточну папку). -Використання `cd` із `..` змінить вашу поточну директорію на батьківську (тобто папка, що містить вашу поточну папку). +Перевірте, де ми: -Перевірте де ми: + + +{% filename %}command-line{% endfilename %} $ pwd /Users/olasitarska/Desktop + + + + + -Windows: +{% filename %}command-line{% endfilename %} > cd C:\Users\olasitarska\Desktop + + + Тепер час видалити директорію `practice`: -> __Увага__: Видалення файлів за допомогою `del`, `rmdir` або `rm` є безповоротнім, тобто *файли будуть видалені назавжди*! То ж, будьте конче обережними із цими командами. +> **Увага**: Видалення файлів за допомогою `del`, `rmdir` або `rm` є безповоротнім, тобто *файли будуть видалені назавжди*! Тож будьте конче обережними з цією командою. + + + +{% filename %}command-line{% endfilename %} $ rm -r practice + + + + + -Windows: +{% filename %}command-line{% endfilename %} > rmdir /S practice practice, Are you sure ? Y + -Виконано! Щоб переконатися, що папку дійсно видалена, давайте перевіримо: + + +Виконано! Щоб переконатися, що папку дійсно видалено, давайте перевіримо: + + + +{% filename %}command-line{% endfilename %} $ ls + -Windows: + + + + +{% filename %}command-line{% endfilename %} > dir + + + ### Вихід -Це все наразі! Можна тепер спокійно закрити командний рядок. Давайте зробимо це хакерським методом, добре?:) +Це все наразі! Можна тепер спокійно закрити командний рядок. Давайте зробимо це хакерським методом, добре? :) + + + +{% filename %}command-line{% endfilename %} $ exit + + + -Windows: + + +{% filename %}command-line{% endfilename %} > exit + + + -Круто, га?:) +Круто, га? :) ## Підсумок -Тут наведено підсумок деяких корисних команд: +Для зручності ми зібрали основні команди у таблиці: -| Команда (Windows) | Команда (Mac OS / Linux) | Опис | Приклад | -| ----------------- | ------------------------ | ------------------------ | ------------------------------------------------- | -| exit | exit | закрити вікно | **exit** | -| cd | cd | змінити директорію | **cd test** | -| dir | ls | список директорій/файлів | **dir** | -| copy | cp | скопіювати файл | **copy c:\test\test.txt c:\windows\test.txt** | -| move | mv | перемістити файл | **move c:\test\test.txt c:\windows\test.txt** | -| mkdir | mkdir | створити нову директорію | **mkdir testdirectory** | -| del | rm | видалити директорію/файл | **del c:\test\test.txt** | +| Команда (Windows) | Команда (Mac OS / Linux) | Опис | Приклад | +| ----------------- | ------------------------ | ---------------------------- | --------------------------------------------------- | +| exit | exit | закрити вікно | **exit** | +| cd | cd | змінити директорію | **cd test** | +| cd | pwd | показати поточну директорію | **cd** (Windows) або **pwd** (Mac OS / Linux) | +| dir | ls | список директорій/файлів | **dir** | +| copy | cp | скопіювати файл | **copy c:\test\test.txt c:\windows\test.txt** | +| move | mv | перемістити файл | **move c:\test\test.txt c:\windows\test.txt** | +| mkdir | mkdir | створити нову директорію | **mkdir testdirectory** | +| del | rm | видалити файл | **del c:\test\test.txt** | +| rmdir /s | rm -r | видалити директорію | **rm -r testdirectory** | +| [CMD] /? | man [CMD] | показати довідку для команди | **cd /?** (Windows) або **man cd** (Mac OS / Linux) | -Тут наведено лише невелику кількість команд, котрі можна запускати у вашому командному рядку, однак, на даний момент ми не збираємося використовувати щось більше. +Це лише невелика кількість команд, які можна запускати у вашому командному рядку, однак поки вам більше і не буде потрібно. -Якщо вас цікавить, [ss64.com](http://ss64.com) містить повний список посилань на команди для усіх операційних систем. +Якщо вас цікавить, [ss64.com](http://ss64.com) містить опис усіх команд для усіх операційних систем. ## Готові? -Давайте зануримось у Python! +Давайте зануримось у Python! \ No newline at end of file diff --git a/uk/intro_to_command_line/open_instructions.md b/uk/intro_to_command_line/open_instructions.md new file mode 100644 index 00000000000..a3ab5b6c114 --- /dev/null +++ b/uk/intro_to_command_line/open_instructions.md @@ -0,0 +1,28 @@ + + +В залежності від вашої версії Windows і клавіатури, ви можете відкрити командне вікно одним з наступних способів (можливо, доведеться трохи поекспериментувати, але ви не повинні пробувати всі варіанти): + +- Перейдіть до меню Пуск (або екрана Пуск), та введіть "Командний рядок" ("Command Prompt") у полі пошуку. +- Перейдіть до меню Пуск → Система Windows → Командний рядок (Start menu → Windows System → Command Prompt). +- Перейдіть до меню Пуск → Усі програми → Стандартні → Командний рядок (Start menu → All Programs → Accessories → Command Prompt). +- Перейдіть до екрана Пуск, підведіть курсор миші до нижнього лівого кута екрану та натисніть стрілку вниз, яка з'явиться (на сенсорному екрані замість цього протягніть від нижнього краю екрану). Повинна відкритись сторінка додатків. Натисніть на "Командний рядок" ("Command Prompt") у розділі "Система Windows" ("Windows System"). +- Утримуючи спеціальну клавішу "Windows" на клавіатурі, натисніть клавішу "X". Виберіть "Командний рядок" ("Command Prompt") або "Оболонка Windows PowerShell" із меню, яке з'явиться. +- Утримуючи клавішу "Windows", натисніть клавішу "R", щоб відкрити вікно "Виконати". Введіть "cmd" у текстовому полі та натисніть кнопку "OK". + +![Введіть "cmd" у вікні "Виконати"](../python_installation/images/windows-plus-r.png) + +Пізніше, в цьому посібнику вам знадобиться два командних вікна, відчинених одночасно. Однак, на деяких версіях Windows, якщо у вас вже є одне відчинене вікно і ви спробуєте відкрити друге за допомогою того ж методу, вас переадресує знову на те ж командне вікно, що вже відкрите. Спробуйте це зараз на своєму комп'ютері та подивіться, що станеться! Якщо ви отримуєте лише одне командне вікно, то спробуйте якийсь інший метод зі списку вище. Принаймні один з них повинен відкривати нове командне вікно. + + + + + +Відкрийте Додатки → Утиліти → Термінал (Applications → Utilities → Terminal). + + + + + +Скоріш за все Додатки → Стандартні → Термінал (Applications → Accessories → Terminal), або Додатки → Система → Термінал (Applications → System → Terminal), але це може залежати від вашого дистрибутива. Якщо ж немає нічого подібного, спробуйте погуглити це. :) + + \ No newline at end of file diff --git a/uk/python_installation/README.md b/uk/python_installation/README.md index 48b6f8aabae..22ca3becc3c 100644 --- a/uk/python_installation/README.md +++ b/uk/python_installation/README.md @@ -2,13 +2,14 @@ Нарешті ми тут! -Але спершу, дозвольте нам розказати вам що ж таке Python. Python - це дуже популярна мова програмування, що може використовуватися для створення веб сайтів, ігор, наукових програм, графіки та багато-багато іншого. +Але спершу дозвольте нам розповісти вам, що ж таке Python. Python – це дуже популярна мова програмування, що може використовуватися для створення вебсайтів, ігор, наукових програм, графіки та багато-багато іншого. -Python розроблено наприкінці 80-х, і його головною ціллю є читабельність для людей (не тільки для машин!). Саме тому ця мова виглядає набагато простіше, ніж інші мови програмування. Це привносить простоту у процес вивчення, але не турбуйтеся, Python водночас є дуже потужним! +Python бере свій початок з кінця 80-х, і його головною метою є бути читабельним для людей (а не тільки для машин!). Саме тому ця мова виглядає набагато простіше, ніж інші мови програмування. Але не турбуйтеся, Python водночас є дуже потужним! # Встановлення Python -> **Примітка** Якщо ви вже прошли розділ установки, немає потреби робити це знову - можна пропустити і перейти відразу до наступного розділу! - -{% include "/python_installation/instructions.md" %} +> **Примітка:** Якщо ви використовуєте хромбук, пропустіть цей розділ і переконайтеся, що ви слідуєте інструкції [ Встановлення (хромбук)](../chromebook_setup/README.md). +> +> **Примітка:** Якщо ви вже пройшли [кроки встановлення](../installation/README.md), нема потреби робити це знову – можна пропустити це і перейти одразу до наступного розділу! +{% include "/python_installation/instructions.md" %} \ No newline at end of file diff --git a/uk/python_installation/instructions.md b/uk/python_installation/instructions.md index 7a5fdad6cb5..f1a54cdc10a 100644 --- a/uk/python_installation/instructions.md +++ b/uk/python_installation/instructions.md @@ -1,60 +1,117 @@ - +> Для читачів вдома: відеоверсія цього розділу (разом із наступним) - [Встановлення Python та редактора коду](https://www.youtube.com/watch?v=pVTaqzKZCdA) (англ.). +> > Цей розділ базується на навчальних матеріалах Geek Girls Carrots (https://github.com/ggcarrots/django-carrots) -Django написаний на Python. Нам потрібен Python, щоб робити усе, що заманеться на Django. Почнемо з його інсталяції! Ми хочемо встановити Python 3.4, отже якщо ви вже маєте якусь більш ранню версію, то необхідно її оновити. +Django написаний на Python. Нам потрібен Python, щоб робити на Django усе, що заманеться. Почнемо з його інсталяції! Ми хочемо, щоб ви встановили останню версію Python 3, отже якщо у вас встановлена більш рання версія, вам потрібно її оновити. Якщо у вас вже є версія {{ book.py_min_version }} або вище, то у вас має бути все гаразд. + +Будь ласка, встановіть звичайний Python, навіть якщо на вашому комп’ютері встановлена Анаконда. + + + +Спочатку перевірте, яка версія Windows встановлена на вашому комп'ютері (64- чи 32-розрядна) у рядку "Тип системи" сторінки налаштувань "Система". Щоб відкрити цю сторінку, оберіть один з цих способів: + +* Натисніть на клавіатурі комбінацію клавіш Win + Pause/Break +* Відкрийте панель керування у меню Windows, потім перейдіть до категорії "Системи й безпека", і звідти - до "Система" +* Натисніть клавішу Windows, а потім перейдіть до Настройки > Система > Про систему +* Знайдіть у меню "Пуск" розділ "Система". Для цього натисніть кнопку «Пуск» (або клавішу Windows), а потім почніть набирати `Система`. Посилання на сторінку "Система" з'явиться одразу, як тільки ви почнете набирати. І ви можете одразу обрати його. + +Python для Windows можна завантажити з сайту https://www.python.org/downloads/windows/. Натисніть на посилання "Latest Python 3 Release - Python 3.x.x". Якщо ваш комп'ютер працює з **64-розрядною** версією Windows, завантажте **Windows installer (64-bit)** (посилання шукайте у самому низу). Інакше завантажте **Windows installer (32-bit)**. Після завантаження інсталятора запустіть його (двічі клацніть на ньому) і виконайте усі подальші інструкції. + +Зверніть увагу на одну річ: під час встановлення з'явиться вікно з заголовком "Setup". Переконайтесь, що ви поставили галочку "Add Python {{ book.py_version }} to PATH" або "Add Python to your environment variables", і натисніть "Install Now", як показано тут (це може виглядати трохи інакше, якщо ви встановлюєте іншу версію): + +![Не забудьте додати Python до змінної Path](../python_installation/images/python-installation-options.png) + +Коли встановлення завершиться, ви можете побачити діалогове вікно з посиланням, щоб дізнатись більше про Python або про версію, яку ви встановили. Закрийте або скасуйте цей діалог: у цьому посібнику ви дізнаєтесь значно більше! + +Примітка: Якщо ви використовуєте стару версію Windows (7, Vista, або будь-яка стара версія) і встановлення Python {{ book.py_version }} зазнає помилки, то встановіть усі оновлення для Windows і спробуйте встановити Python знову. Якщо помилка залишилась, спробуйте встановити версію Python {{ book.py_min_release }} з [Python.org](https://www.python.org/downloads/windows/). + +> Django {{ book.django_version }} потребує Python {{ book.py_min_version }} або вище: ці версії не підтримують Windows XP або більш ранні версії Windows. + + + -### Windows +> **Зверніть увагу:** Перед встановленням Python на OS X, ви повинні впевнитись, що налаштування Mac дозволяють встановлювати пакети, які відсутні з App Store. Перейдіть до налаштувань системи (це у папці Applications), натисніть "Security & Privacy", а потім - вкладку "General". Якщо параметр "Allow apps downloaded from:" встановлено в "Mac App Store", змініть його на "Mac App Store and identified developers". -Python для Windows можна завантажити з сайту https://www.python.org/downloads/release/python-343/. Після завантаження файлу ***.msi**, ви повинні запустити його (натисніть по ньому двічі) і виконувати усі подальші інструкції. Важливо пам'ятати шлях (директорію), де ви встановили Python. Це знадобиться пізніше! +Вам необхідно перейти на вебсайт https://www.python.org/downloads/mac-osx/ і завантажити найсвіжіший інсталятор Python: -Зверніть увагу на другу сторінку "Customize" майстера установки, вам потрібно пролистати вниз і вибрати опцію "Add python.exe to the Path" (додати python.exe в системну змінну Path), як показано тут: +* завантажте файл *Mac OS X 64-bit/32-bit installer*, +* двічі клацніть на *python-{{ book.py_release }}-macosx10.9.pkg*, щоб запустити інсталятор. + + -![Не забудьте додати Python до змінної Path](../python_installation/images/add_python_to_windows_path.png) + -### Linux +Цілком ймовірно, що у вас вже є Python, встановлений разом із системою. Щоб перевірити це (а заодно й версію), відкрийте консоль і наберіть таку команду: -Цілком ймовірно, що у вас вже є Python встановлений разом із системою. Щоб перевірити це (а заодно й версію), відкрийте консоль і наберіть наступну команду: +{% filename %}command-line{% endfilename %} $ python3 --version - Python 3.4.3 + Python {{ book.py_release }} + + +Якщо у вас встановлена інша версія Python, але не старіша за {{ book.py_min_version }} (напр. {{ book.py_min_release }}), то оновлювати не потрібно. Якщо ж у вас не встановлено Python, або якщо ви хочете оновити версію, спочатку перевірте, яку версію дистрибутиву Linux ви використовуєте за допомогою наступної команди: -Якщо Python не встановлено або ви бажаєте встановити іншу версію, то можете виконати встановлення наступним чином: +{% filename %}command-line{% endfilename %} + $ grep '^NAME=' /etc/os-release + -#### Debian або Ubuntu +Після цього, в залежності від результату, дотримуйтесь однієї з наступних інструкцій (див. нижче). + + + + Наберіть наступну команду в консолі: - $ sudo apt install python3.4 +{% filename %}command-line{% endfilename %} + + $ sudo apt install python3 + + -#### Fedora + Скористайтеся наступною командою в консолі: - $ sudo dnf install python3.4 +{% filename %}command-line{% endfilename %} + $ sudo dnf install python3 + -#### openSUSE +Якщо у вас стара версія Fedora, ви можете отримати помилку, що команда `dnf` не знайдена. У цьому випадку потрібно використати `yum`. + + + + Скористайтеся наступною командою в консолі: +{% filename %}command-line{% endfilename %} + $ sudo zypper install python3 + + -### OS X +Перевірте, що встановлення пройшло успішно, відкривши командний рядок і запустивши команду `python3`: -Вам необхідно перейти на веб сайт https://www.python.org/downloads/release/python-343/ і завантажити Python інсталятор: +{% filename %}command-line{% endfilename %} -* завантажте файл *Mac OS X 64-bit/32-bit installer*, -* Двічі клацніть на *python 3.4.3 macosx10.6.pkg*, щоб запустити інсталятор. + $ python3 --version + Python {{ book.py_release }} + -Підтвердіть, що інсталяція пройшла успішно відкривши програму *Terminal* і запустивши команду `python3`: +Версія може відрізнятися від {{ book.py_release }} -- вона має відповідати встановленій вами версії. - $ python3 --version - Python 3.4.3 +**ПРИМІТКА:** Якщо ви у Windows і отримуєте повідомлення про помилку, що `python3` не знайдено, спробуйте використати `python` (без `3`) і перевірте, що версія Python не менше за {{ book.py_min_version }}. Якщо це не спрацювало, ви можете відкрити новий командний рядок і спробувати знову; подібне відбувається, якщо ви використовуєте командний рядок, що був відкритий ще до початку встановлення Python. ----- +* * * -Якщо маєте певні сумніви, або щось пішло не так і ви без поняття, що робити далі - будь ласка, зверніться до свого тренера! Інколи не все йде гладко і краще звернутись по допомогу до когось, хто має більше досвіду. +Якщо маєте певні сумніви, або щось пішло не так і ви без поняття, що робити далі - будь ласка, зверніться до свого тренера! Інколи не все йде гладко і краще звернутись по допомогу до когось, хто має більше досвіду. \ No newline at end of file diff --git a/uk/python_introduction/README.md b/uk/python_introduction/README.md index a1609ae2b95..e639f79f65d 100644 --- a/uk/python_introduction/README.md +++ b/uk/python_introduction/README.md @@ -1,502 +1,736 @@ +{% set warning_icon = '' %} + # Вступ до Python > Частина цього розділу базується на матеріалах Geek Girls Carrots (https://github.com/ggcarrots/django-carrots). Давайте напишемо якийсь код! -## Командний рядок Python - -Щоб розпочати роботу із Python, нам необхідно відкрити *командний рядок*. Ви вже повинні знати як це зробити, адже ознайомились із цим у розділі [Вступ до командного рядка](../intro_to_command_line/README.md). +{% include "/python_introduction/prompt.md" %} -Як тільки будете готові, виконайте наведені нижче інструкції. +## Your first Python command! -Ми хочемо відкрити консоль Python, тому введіть `python` на Windows або `python3` на Mac OS/Linux та натисніть `Enter`. +After running the Python command, the prompt changed to `>>>`. For us this means that for now we may only use commands in the Python language. You don't have to type in `>>>` – Python will do that for you. - $ python3 - Python 3.4.3 (...) - Type "help", "copyright", "credits" or "license" for more information. - >>> +If you want to exit the Python console at any point, type `exit()` or use the shortcut `Ctrl + Z` for Windows and `Ctrl + D` for Mac/Linux. Then you won't see `>>>` any longer. -## Ваша перша команда на Python! +For now, we don't want to exit the Python console. We want to learn more about it. Let's start by typing some math, like `2 + 3` and hitting `enter`. -Після запуску команди Python командний рядок зміниться на `>>>`. Для нас це означає, що відтепер ми можемо користуватися лише командами мови Python. Вам не доведеться друкувати `>>>` - Python зробить це для вас сам. +{% filename %}command-line{% endfilename %} -Якщо забажаєте вийти із консолі Python, просто наберіть `exit()` або використайте комбінацію `Ctrl + Z` для Windows і `Ctrl + D` для Mac/Linux. Після того ви більше не побачите `>>>`. - -Але наразі, ми не бажаємо виходити із консолі Python. Ми хочемо дізнатися про неї більше. Почнемо з чогось простенького. Наприклад, спробуйте виконати певні алгебраїчні операції, на зразок `2 + 3` та натисніть `enter`. +```python +>>> 2 + 3 +5 +``` - >>> 2 + 3 - 5 +Nice! See how the answer popped out? Python knows math! You could try other commands like: -Чудово! Бачите, яким чином здійснено вивід відповіді? Python знає математику! Можна спробувати інші команди, наприклад: - `4 * 5` - `5 - 1` - `40 / 2` -Поки що можете трохи побавитися із математикою, а далі повертайтесь назад :). +To perform exponential calculation, say 2 to the power 3, we type: {% filename %}command-line{% endfilename %} + +```python +>>> 2 ** 3 +8 +``` + +Have fun with this for a little while and then get back here. :) + +As you can see, Python is a great calculator. If you're wondering what else you can do… + +## Strings + +How about your name? Type your first name in quotes like this: -Як бачите, Python є чудовим калькулятором. Хіба вас не цікавить, що ще можна робити... +{% filename %}command-line{% endfilename %} -## Рядки +```python +>>> "Ola" +'Ola' +``` -Як щодо вашого імені? Наберіть ваше ім'я в лапках, як тут: +You've now created your first string! It's a sequence of characters that can be processed by a computer. The string must always begin and end with the same character. This may be single (`'`) or double (`"`) quotes (there is no difference!) The quotes tell Python that what's inside of them is a string. - >>> "Ola" - 'Ola' +Strings can be strung together. Try this: -Щойно ви створили свій перший рядок! Це послідовність символів, що може бути оброблена комп'ютером. Рядок має постійно починатися і закінчуватися одним і тим же символом. Це може бути одинарна (`'`) або подвійна (`"`) лапка (немає ніякої різниці)! Лапки вказують Python, що всередині них рядок. +{% filename %}командний рядок{% endfilename %} -Рядки можна об'єднувати. Спробуйте: +```python +>>> "Hi there " + "Ola" +'Hi there Ola' +``` - >>> "Hi there " + "Ola" - 'Hi there Ola' +You can also multiply strings with a number: -Також можна множити рядки на число: +{% filename %}command-line{% endfilename %} - >>> "Ola" * 3 - 'OlaOlaOla' +```python +>>> "Ola" * 3 +'OlaOlaOla' +``` -Якщо вам раптом треба поставити апостроф всередині рядка, то існує два шляхи це зробити. +If you need to put an apostrophe inside your string, you have two ways to do it. -Використавши подвійні лапки: +Using double quotes: - >>> "Runnin' down the hill" - "Runnin' down the hill" +{% filename %}командний рядок{% endfilename %} -або ж екранувати апостроф за допомогою оберненої косої риски (англ. backslash `\`): +```python +>>> "Runnin' down the hill" +"Runnin' down the hill" +``` - >>> 'Runnin\' down the hill' - "Runnin' down the hill" +or escaping the apostrophe with a backslash (`\`): -Гарно, еге ж? Щоб побачити своє ім'я, написане великими літерами, наберіть: +{% filename %}command-line{% endfilename %} - >>> "Ola".upper() - 'OLA' +```python +>>> 'Runnin\' down the hill' +"Runnin' down the hill" +``` -Ви щойно застосували до свого рядка `upper` __функцію__! Функція (така як `upper()`) - це набір інструкцій, які повинен виконувати Python над заданим об'єктом (`"Ola"`) з моменту її виклику. +Nice, huh? To see your name in uppercase letters, type: -Якщо ви раптом забажаєте дізнатися про число літер, що містяться у вашому імені, то для цього також існує функція! +{% filename %}command-line{% endfilename %} - >>> len("Ola") - 3 +```python +>>> "Ola".upper() +'OLA' +``` -Здивовані, чому іноді ви викликаєте функції із `.` наприкінці рядка (на зразок `"Ola".upper()`), а іноді ви спочатку викликаєте функцію і вказуєте рядок у дужках? Що ж, в деяких випадках, функції належать об'єктам, як `upper()`, котра може бути виконана лише над рядком. У цьому випадку, ми називаємо функцію __методом__. Іншого разу, функції не належать до жодного об'єкту і можуть використовуватись стосовно різних типів об'єктів, як `len()`. Саме тому ви використовуємо `"Ola"` у якості параметра для функції `len`. +You just used the `upper` **method** on your string! A method (like `upper()`) is a sequence of instructions that Python has to perform on a given object (`"Ola"`) once you call it. + +If you want to know the number of letters contained in your name, there is a **function** for that too! + +{% filename %}командний рядок{% endfilename %} + +```python +>>> len("Ola") +3 +``` + +Wonder why sometimes you call functions with a `.` at the end of a string (like `"Ola".upper()`) and sometimes you first call a function and place the string in parentheses? Well, in some cases, functions belong to objects, like `upper()`, which can only be performed on strings. In this case, we call the function a **method**. Other times, functions don't belong to anything specific and can be used on different types of objects, just like `len()`. That's why we're giving `"Ola"` as a parameter to the `len` function. ### Підсумок -Гаразд, досить стосовно рядків. Отже, ви вже ознайомилися із такими поняттями як: +OK, enough of strings. So far you've learned about: -- __командний рядок__ - набір команд (коду) в командному рядку Python дає результат у відповідях на Python -- __числа і рядки__ - в Python числа використовуються для математичних розрахунків, а рядки - для текстових об'єктів -- __оператори__ - на зразок + та \*, комбінують значення і продукують нове -- __функції__ - на зразок upper() та len(), виконують дії над об'єктами. +- **консоль** – виконання команд (інструкцій коду) в консолі Python одразу показує їхній результат +- **числа і рядки** – в Python числа використовуються для математичних виразів, а рядки – для текстових об'єктів +- **оператори** – на зразок `+` та `*`, перетворюють одні значення на інші +- **функції** – на зразок `upper()` та `len()`, виконують дії над об'єктами. -Це є основи кожної мови програмування, яку ви вивчатимете. Готові приступити до чогось складнішого? Б'ємось об заклад, що так! +These are the basics of every programming language you learn. Ready for something harder? We bet you are! -## Помилки +## Errors -Спробуємо щось нове. Чи можемо ми отримати довжину числа тим же методом, як ми це робили для нашого імені? Наберіть `len(304023)` та натисніть `Enter`: +Let's try something new. Can we get the length of a number the same way we could find out the length of our name? Type in `len(304023)` and hit `enter`: - >>> len(304023) - Traceback (most recent call last): - File "", line 1, in - TypeError: object of type 'int' has no len() +{% filename %}{{ warning_icon }} command-line{% endfilename %} -Ми отримали нашу першу помилку! Вона говорить про те, що об'єкт типу "int" (integers, цілі числа) не має довжини. І що ж нам тепер робити? Можливо, можна записати наше число у формі рядка? Рядки ж мають довжину, правда? +```python +>>> len(304023) +Traceback (most recent call last): + File "", line 1, in +TypeError: object of type 'int' has no len() +``` - >>> len(str(304023)) - 6 +We got our first error! The {{ warning_icon }} icon is our way of giving you a heads up that the code you are about to run won't work as expected. Making mistakes (even intentional ones) are an important part of learning! -Спрацювало! Ми використали функцію `str` всередині функції `len`. `str()` перетворює будь-що на рядки. +It says that objects of type "int" (integers, whole numbers) have no length. So what can we do now? Maybe we can write our number as a string? Strings have a length, right? -- Функція `str` перетворює речі на __рядки__ -- Функція `int` перетворює речі на __цілі числа__ +{% filename %}command-line{% endfilename %} -> Важливо: ми можемо перетворювати числа на текст, однак, не можемо перетворити текст на числа - чому б дорівнювало `int('hello')`? +```python +>>> len(str(304023)) +6 +``` -## Змінні +It worked! We used the `str` function inside of the `len` function. `str()` converts everything to strings. -Важливою концепцію в програмуванні є змінні. Змінна - це ніщо більше, ніж ім'я для чогось, що можна буде використовувати пізніше. Програмісти використовують ці змінні для збереження даних, щоб зробити свій код більш читабельним і, таким чином, їм не потрібно пам'ятати зайве. +- Функція `str` перетворює будь-який об'єкт на **рядок** +- Функція `int` перетворює будь-який об'єкт на **ціле число** (якщо це можливо) -Скажімо, ми хочемо створити змінну і назвати її `name`: +> Important: we can convert numbers into text, but we can't necessarily convert text into numbers – what would `int('hello')` be anyway? - >>> name = "Ola" +## Variables -Бачите? Це просто! Просто: name дорівнює Ola. +An important concept in programming is variables. A variable is nothing more than a name for something so you can use it later. Programmers use these variables to store data, make their code more readable and so they don't have to keep remembering what things are. -Як ви зауважили, ваша програма не повернула нічого як вона це робила до того. Отже, як ми впевнимось, що змінна насправді існує? Просто введіть `name` і натисніть `enter`: +Let's say we want to create a new variable called `name`: - >>> name - 'Ola' +{% filename %}command-line{% endfilename %} -Урра! Ваша перша змінна :)! Ви завжди можете змінити значення, на яке вона посилатиметься: +```python +>>> name = "Ola" +``` - >>> name = "Sonja" - >>> name - 'Sonja' +We type name equals Ola. -Також можна використовувати її у функціях: +As you've noticed, your program didn't return anything like it did before. So how do we know that the variable actually exists? Enter `name` and hit `enter`: - >>> len(name) - 5 +{% filename %}командний рядок{% endfilename %} -Файно, хіба ні? Звісно, змінні можуть представляти будь-що, числа також! Спробуйте: +```python +>>> name +'Ola' +``` - >>> a = 4 - >>> b = 6 - >>> a * b - 24 +Yippee! Your first variable! :) You can always change what it refers to: -А якщо ми використали неправильне ім'я? Чи можете ви передбачити, що станеться? Спробуймо! +{% filename %}command-line{% endfilename %} - >>> city = "Tokyo" - >>> ctiy - Traceback (most recent call last): - File "", line 1, in - NameError: name 'ctiy' is not defined +```python +>>> name = "Sonja" +>>> name +'Sonja' +``` -Помилка! Як бачите, Python має різні типи помилок і дана помилка називається **NameError**. Python виведе для вас цю помилку, якщо ви спробуєте використати досі не визначену змінну. Якщо ж ви зіткнетеся із цією помилкою пізніше, перевірте свій код, чи не зробили ви помилки в написанні імен змінних. +You can use it in functions too: -Поекспериментуйте із цим усім і подивіться, що можна робити! +{% filename %}command-line{% endfilename %} +```python +>>> len(name) +5 +``` -## Функція print +Awesome, right? Now, variables can be anything – numbers too! Try this: -Спробуйте наступне: +{% filename %}command-line{% endfilename %} - >>> name = 'Maria' - >>> name - 'Maria' - >>> print(name) - Maria +```python +>>> a = 4 +>>> b = 6 +>>> a * b +24 +``` -Коли ви просто набираєте `name`, Python інтерпретує відповіді за допомогою рядкового *представлення* змінної 'name', котра є набором літер M-a-r-i-a, взятим в одинарні лапки, ''. Коли ви повідомляєте `print(name)`, Python "надрукує" значення змінної на екран, без лапок, що є більш акуратним. +But what if we used the wrong name? Can you guess what would happen? Let's try! -Як ми потім побачимо, `print()` є також корисним коли ми хочемо надрукувати речі з внутрішніх функцій, або ж коли хочемо надрукувати речі в декілька рядків. +{% filename %}{{ warning_icon }} command-line{% endfilename %} +```python +>>> city = "Tokyo" +>>> ctiy +Traceback (most recent call last): + File "", line 1, in +NameError: name 'ctiy' is not defined +``` -## Списки +An error! As you can see, Python has different types of errors and this one is called a **NameError**. Python will give you this error if you try to use a variable that hasn't been defined yet. If you encounter this error later, check your code to see if you've mistyped any names. -Окрім рядків та чисел, Python має усі види різних типів об'єктів. Наразі ми збираємося представити вашій увазі один із них, що називається __список__. Списки є саме тим, про що ви й подумали: це об'єкти, що є списками інших об'єктів :) +Play with this for a while and see what you can do! -Створимо список: +## The print function - >>> [] - [] +Try this: -Так, цей список пустий. Не дуже корисно, чи не так? Створимо список лотерейних чисел. Ми не бажаємо увесь час повторюватись, тож покладемо усе до змінної: +{% filename %}command-line{% endfilename %} - >>> lottery = [3, 42, 12, 19, 30, 59] +```python +>>> name = 'Maria' +>>> name +'Maria' +>>> print(name) +Maria +``` + +When you just type `name`, the Python interpreter responds with the string *representation* of the variable 'name', which is the letters M-a-r-i-a, surrounded by single quotes, ''. When you say `print(name)`, Python will "print" the contents of the variable to the screen, without the quotes, which is neater. + +As we'll see later, `print()` is also useful when we want to print things from inside functions, or when we want to print things on multiple lines. + +## Lists -Гаразд, маємо список! Що ми можемо із цим робити? Давайте глянемо скільки лотерейних номерів міститься у списку. Не маєте жодного уявлення, яку функцію для цього можна використати? Ви вже це знаєте! +Beside strings and integers, Python has all sorts of different types of objects. Now we're going to introduce one called **list**. Lists are exactly what you think they are: objects which are lists of other objects. :) - >>> len(lottery) - 6 +Go ahead and create a list: + +{% filename %}command-line{% endfilename %} + +```python +>>> [] +[] +``` + +Yes, this list is empty. Not very useful, right? Let's create a list of lottery numbers. We don't want to repeat ourselves all the time, so we will put it in a variable, too: + +{% filename %}command-line{% endfilename %} + +```python +>>> lottery = [3, 42, 12, 19, 30, 59] +``` -Так! `len()` може дати вам кількість об'єктів у списку. Зручно, правда ж? Може, тепер здійснимо сортування: +All right, we have a list! What can we do with it? Let's see how many lottery numbers there are in a list. Do you have any idea which function you should use for that? You know this already! - >>> lottery.sort() +{% filename %}command-line{% endfilename %} -Ця функція нічого не повертає, вона лише змінює порядок, в якому з'являються числа у списку. Давайте надрукуємо список знову і подивимось, що ж трапилося: +```python +>>> len(lottery) +6 +``` - >>> print(lottery) - [3, 12, 19, 30, 42, 59] +Yes! `len()` can give you a number of objects in a list. Handy, right? Maybe we will sort it now: -Як бачимо, числа у вашому списку тепер відсортовано починаючи з найменшого і закінчуючи найбільшим значенням. Вітаємо! +{% filename %}command-line{% endfilename %} -Можливо, ми хочемо відсортувати числа у зворотньому порядку? Давайте це зробимо! +```python +>>> lottery.sort() +``` - >>> lottery.reverse() - >>> print(lottery) - [59, 42, 30, 19, 12, 3] +This doesn't return anything, it just changed the order in which the numbers appear in the list. Let's print it out again and see what happened: -Просто, чи не так? Якщо ви забажаєте щось додати до свого списку, то можете це зробити за допомогою наступної команди: +{% filename %}command-line{% endfilename %} - >>> lottery.append(199) - >>> print(lottery) - [59, 42, 30, 19, 12, 3, 199] +```python +>>> print(lottery) +[3, 12, 19, 30, 42, 59] +``` -Якщо захочете показати лише перше число, то можете зробити це використавши __індекси__. Індекс - це номер, що повідомляє про те, звідки у списку взято елемент. Програмісти вважають за краще рахувати з 0, таким чином, перший об'єкт у списку має індекс 0, наступний - 1 і так далі. Спробуйте наступне: +As you can see, the numbers in your list are now sorted from the lowest to highest value. Congrats! - >>> print(lottery[0]) - 59 - >>> print(lottery[1]) - 42 +Maybe we want to reverse that order? Let's do that! -Як бачимо, ви можете отримати доступ до різних об'єктів списку використавши ім'я списку та індекс об'єкта всередині квадратних дужок. +{% filename %}командний рядок{% endfilename %} -Для того, щоб видалити що-небудь із списку, вам потрібно використовувати вище вивчені __індекси__ і команду `pop()`. Давайте спробуємо на прикладі та нагадаємо, що ми вивчили раніше; ми будемо видаляти перший елемент з нашого списку. +```python +>>> lottery.reverse() +>>> print(lottery) +[59, 42, 30, 19, 12, 3] +``` - >>> print(lottery) - [59, 42, 30, 19, 12, 3, 199] - >>> print(lottery[0]) - 59 - >>> lottery.pop(0) - >>> print(lottery) - [42, 30, 19, 12, 3, 199] +If you want to add something to your list, you can do this by typing this command: -Працює чудово! +{% filename %}command-line{% endfilename %} -Для додаткового задоволення, спробуйте деякі індекси: 6, 7, 1000, -1, -6 або -1000. Подивіться, чи здатні ви передбачити результат команди перед її застосуванням. Чи мають ці результати якийсь смисл? +```python +>>> lottery.append(199) +>>> print(lottery) +[59, 42, 30, 19, 12, 3, 199] +``` -Список усіх доступних методів для списку міститься у цьому розділі документації з Python: https://docs.python.org/3/tutorial/datastructures.html +If you want to show only the first number, you can do this by using **indexes**. An index is the number that says where in a list an item occurs. Programmers prefer to start counting at 0, so the first object in your list is at index 0, the next one is at 1, and so on. Try this: -## Словники +{% filename %}command-line{% endfilename %} -Словник є чимось подібним до списку, але доступ до значень отримується шляхом пошуку за ключем замість індексу. Ключ може являти собою будь-який рядок або число. Синтаксис для визначення пустого словника: +```python +>>> print(lottery[0]) +59 +>>> print(lottery[1]) +42 +``` - >>> {} - {} +As you can see, you can access different objects in your list by using the list's name and the object's index inside of square brackets. -Це показує, що ви просто створили пустий словник. Урра! +To delete something from your list you will need to use **indexes** as we learned above and the `pop()` method. Let's try an example and reinforce what we learned previously; we will be deleting the first number of our list. -А тепер спробуйте набрати наступну команду (спробуйте також замінити на вашу власну інформацію): +{% filename %}командний рядок{% endfilename %} + +```python +>>> print(lottery) +[59, 42, 30, 19, 12, 3, 199] +>>> print(lottery[0]) +59 +>>> lottery.pop(0) +59 +>>> print(lottery) +[42, 30, 19, 12, 3, 199] +``` + +That worked like a charm! + +For extra fun, try some other indexes: 6, 7, 1000, -1, -6 or -1000. See if you can predict the result before trying the command. Do the results make sense? + +You can find a list of all available list methods in this chapter of the Python documentation: https://docs.python.org/3/tutorial/datastructures.html + +## Dictionaries + +> For readers at home: this part is covered in the [Python Basics: Dictionaries](https://www.youtube.com/watch?v=ZX1CVvZLE6c) video. + +A dictionary is similar to a list, but you access values by looking up a key instead of a numeric index. A key can be any string or number. The syntax to define an empty dictionary is: + +{% filename %}command-line{% endfilename %} + +```python +>>> {} +{} +``` + +This shows that you just created an empty dictionary. Hurray! + +Now, try writing the following command (try substituting your own information, too): + +{% filename %}командний рядок{% endfilename %} ```python >>> participant = {'name': 'Ola', 'country': 'Poland', 'favorite_numbers': [7, 42, 92]} ``` -За допомогою вказаної команди ви щойно створили змінну із назвою `participant` і трьома парами ключ-значення: +With this command, you just created a variable named `participant` with three key–value pairs: + +- Ключ `name` (ім'я) вказує на значення `'Ola'` (об'єкт `рядок`), +- `country` (країна) вказує на `'Poland'` (інший `рядок`), +- нарешті, `favorite_number` (улюблені числа) вказує на `[7, 42, 92]` ( `список` з трьома числами всередині). -- ключ `name` вказує на значення `'Ola'` (об'єкт `string` - рядок), -- `country` вказує на `'Poland'` (інший об'єкт `string` - рядок), -- і `favorite_numbers` вказує на `[7, 42, 92]` (об'єкт `list` - список з трьома числами всередині). +You can check the content of individual keys with this syntax: -Можна перевірити значення індивідуальних ключів, використовуючи наступний синтаксис: +{% filename %}командний рядок{% endfilename %} - >>> print(participant['name']) - Ola +```python +>>> print(participant['name']) +Ola +``` -Бачите, усе подібно до списку. Але вам не треба пам'ятати індекс - лише ім'я. +See, it's similar to a list. But you don't need to remember the index – just the name. -Що трапиться, якщо запитати Python про значення ключа, якого не існує? Не здогадуєтесь? Давайте спробуємо і подивимось! +What happens if we ask Python the value of a key that doesn't exist? Can you guess? Let's try it and see! - >>> participant['age'] - Traceback (most recent call last): - File "", line 1, in - KeyError: 'age' +{% filename %}{{ warning_icon }} command-line{% endfilename %} -Погляньте, інша помилка! Цього разу - **KeyError**. Python допомагає і підказує вам про те, що ключа `'age'` не існує в даному словнику. +```python +>>> participant['age'] +Traceback (most recent call last): + File "", line 1, in +KeyError: 'age' +``` + +Look, another error! This one is a **KeyError**. Python is helpful and tells you that the key `'age'` doesn't exist in this dictionary. -Коли ж варто використовувати словник, а коли список? Що ж, гарне питання. Просто вирішимо його подумки перед тим, як подивитися відповідь у наступному рядку. +When should you use a dictionary or a list? Well, that's a good point to ponder. Think about the answer before looking at it in the next line. - Вам необхідна лише впорядкована послідовність елементів? Користуйтеся списком. -- Вам потрібні значення асоційовані із ключами, так що ви можете ефективно переглядати їх (за допомогою ключа) пізніше? Користуйтеся словником. +- Вам потрібні значення, асоційовані із ключами, так щоб ви могли легко їх знаходити (за допомогою ключа)? Користуйтеся словником. -Словники, як і списки, є *змінюваними*, це означає, що вони можуть бути змінені після створення. Ви можете додати нові пари ключ/значення до словника після того, як він був створений, наприклад: +Like lists, using the `len()` function on the dictionaries returns the number of key–value pairs in the dictionary. Go ahead and type in this command: - >>> participant['favorite_language'] = 'Python' +{% filename %}command-line{% endfilename %} -Як і для списків, використання методу `len()` для словників, повертає значення пар ключ-значення в словнику. Наберіть команду: +```python +>>> len(participant) +3 +``` - >>> len(participant) - 4 +Dictionaries, like lists, are *mutable*, meaning that they can be changed after they are created. You can add new key–value pairs to a dictionary after it is created, like this: -Сподіваюся, це наразі має сенс. :) Готові до ще більшого задоволення від роботи зі словниками? Перейдіть на наступний рядок, щоб побачити дещо дивовижне. +{% filename %}command-line{% endfilename %} -Можна використовувати команду `pop()` для видалення елементів зі словника. Скажімо, якщо ви бажаєте видалити значення, що відповідає ключу `'favorite_numbers'`, просто наберіть наступну команду: +```python +>>> participant['favorite_language'] = 'Python' +``` - >>> participant.pop('favorite_numbers') - >>> participant - {'country': 'Poland', 'favorite_language': 'Python', 'name': 'Ola'} +I hope it makes sense up to now. :) Ready for some more fun with dictionaries? Read on for some amazing things. -Як бачимо з результатів, пару ключ-значення, що відповідає ключу 'favorite_numbers' було видалено. +You can use the `pop()` method to delete an item in the dictionary. Say, if you want to delete the entry corresponding to the key `'favorite_numbers'`, type in the following command: -Аналогічно можна змінювати значення, асоційоване з уже існуючим ключем зі словника. Наберіть: +{% filename %}командний рядок{% endfilename %} - >>> participant['country'] = 'Germany' - >>> participant - {'country': 'Germany', 'favorite_language': 'Python', 'name': 'Ola'} +```python +>>> participant.pop('favorite_numbers') +[7, 42, 92] +>>> participant +{'country': 'Poland', 'favorite_language': 'Python', 'name': 'Ola'} +``` -Як бачимо, значення ключа `'country'` було змінено із `'Poland'` на `'Germany'`. :) Вражаюче? Ура! Ви щойно освоїли іншу дивовижну річ. +As you can see from the output, the key–value pair corresponding to the 'favorite_numbers' key has been deleted. + +As well as this, you can also change a value associated with an already-created key in the dictionary. Type this: + +{% filename %}командний рядок{% endfilename %} + +```python +>>> participant['country'] = 'Germany' +>>> participant +{'country': 'Germany', 'favorite_language': 'Python', 'name': 'Ola'} +``` + +As you can see, the value of the key `'country'` has been altered from `'Poland'` to `'Germany'`. :) Exciting? Hurrah! You just learned another amazing thing. ### Підсумок -Чудово! Тепер ви знаєте багато про програмування. У цій останній частині ви дізналися про такі поняття, як: +Awesome! You know a lot about programming now. In this last part you learned about: + +- **помилки** – тепер ви знаєте, як читати та розуміти помилки, які з'являються, якщо Python не розуміє введеної команди; +- **змінні** – імена для об'єктів, що дозволяють вам спростити процес написання коду і зробити його більш читабельним; +- **списки** – послідовності об'єктів, впорядкованих певним чином; +- **словники** – об'єкти, що містять пари ключ-значення. + +Excited for the next part? :) + +## Compare things -- __помилки__ - тепер ви знаєте як читати та розуміти помилки, що з'являються якщо Python не розуміє отриманої команди -- __змінні__ - імена для об'єктів, що дозволяють вам спростити процес написання коду і робить його більш читабельним -- __списки__ - списки певним чином впорядкованих об'єктів -- __словники__ - об'єкти, що зберігають пари ключ-значення +> For readers at home: this part is covered in the [Python Basics: Comparisons](https://www.youtube.com/watch?v=7bzxqIKYgf4) video. -Не дочекаєтеся переходу до наступної частини? :) +A big part of programming involves comparing things. What's the easiest thing to compare? Numbers! Let's see how that works: -## Порівняння +{% filename %}command-line{% endfilename %} -Велика частина програмування включає речі, пов'язані із порівнянням. Що є найпростішою річчю для порівняння? Звісно, числа. Давайте подивимось як це працює: +```python +>>> 5 > 2 +True +>>> 3 < 1 +False +>>> 5 > 2 * 2 +True +>>> 1 == 1 +True +>>> 5 != 2 +True +>>> len([1, 2, 3]) > len([4, 5]) +True +``` - >>> 5 > 2 - True - >>> 3 < 1 - False - >>> 5 > 2 * 2 - True - >>> 1 == 1 - True - >>> 5 != 2 - True +We gave Python some numbers to compare. As you can see, not only can Python compare numbers, but it can also compare values of mathematical expressions like `2 * 2` and function results like the `2` returned by `len([4, 5])`. Nice, huh? -Ми надали Python деякі числа для порівняння. Як бачимо, Python вміє порівнювати не лише числа, а й результати операцій. Гарно, еге ж? +Do you wonder why we put two equal signs `==` next to each other to compare if numbers are equal? We use a single `=` for assigning values to variables. You always, **always** need to put two of them – `==` – if you want to check if things are equal to each other. We can also state that things are unequal to each other. For that, we use the symbol `!=`, as shown in the example above. -Цікаво, чому ми використали два однакові знаки `==`, щоб порівняти на рівність числа? Ми використовуємо `=` для присвоєння значень змінним. Завжди, __завжди__ треба писати `==`, якщо ви бажаєте здійснити перевірку двох чисел на рівність одне одному. Ми також можемо перевіряти, чи два об'єкти є нерівними. Для цього ми використовуємо символ `!=`, як показано в прикладі вище. +Give Python two more tasks: -Задайте для Python ще дві задачі: +{% filename %}command-line{% endfilename %} - >>> 6 >= 12 / 2 - True - >>> 3 <= 2 - False +```python +>>> 6 >= 12 / 2 +True +>>> 3 <= 2 +False +``` -щодо `>` та `<` - усе просто, але що означають `>=` і `<=`? Читайте їх як: +We've seen `>` and `<`, but what do `>=` and `<=` mean? Read them like this: -- x `>` y означає x більше ніж y -- x `<` y означає x менше ніж y -- x `<=` y означає x менше або дорівнює y -- x `>=` y означає x більше або дорівнює y +- x `>` y означає: x більше y +- x `<` y означає: x менше y +- x `<=` y означає: x менше або дорівнює y +- x `>=` y означає: x більше або дорівнює y -Чудово! Хочете ще? Спробуйте це: +Awesome! Wanna do one more? Try this: - >>> 6 > 2 and 2 < 3 - True - >>> 3 > 2 and 2 < 1 - False - >>> 3 > 2 or 2 < 1 - True +{% filename %}командний рядок{% endfilename %} -Ви можете задавати для Python стільки чисел для порівння скільки заманеться, і він дасть вам результат! Дуже розумно, чи не так? +```python +>>> 6 > 2 and 2 < 3 +True +>>> 3 > 2 and 2 < 1 +False +>>> 3 > 2 or 2 < 1 +True +``` -- __and__ - якщо ви використовуєте оператор `and`, обидва порівнюваних значення мають бути істинними - True для того, щоб і уся команда була істинною - True -- __or__ - якщо ви використовуєте оператор `or`, лише одне із порівнюваних значень мають бути істинними - True для того, щоб і уся команда була істинною - True +You can give Python as many numbers to compare as you want, and it will give you an answer! Pretty smart, right? -Чи чули ви про вираз "порівняння яблук і апельсинів"? Давайте спробуємо Python еквівалент: +- **and** – якщо з'єднати дві умови оператором `and` ("та"), то результат буде істинним (True) лише у випадку, коли обидві умови істинні (True); +- **or** – якщо з'єднати дві умови оператором `or` ("або"), то результат буде істинним (True), коли хоча б одна з умов – істинна (True). - >>> 1 > 'django' - Traceback (most recent call last): - File "", line 1, in - TypeError: '>' not supported between instances of 'int' and 'str' +Have you heard of the expression "comparing apples to oranges"? Let's try the Python equivalent: -Бачимо тут, що як і у виразі, Python не в змозі порівняти число (`int`) та рядок (`str`). -Натомість, виводиться **TypeError** і повідомляє нас про те, що ці два типи не можна порівнювати між собою. +{% filename %}{{ warning_icon }} command-line{% endfilename %} -## Логічні типи +```python +>>> 1 > 'django' +Traceback (most recent call last): + File "", line 1, in +TypeError: '>' not supported between instances of 'int' and 'str' +``` + +Here you see that just like in the expression, Python is not able to compare a number (`int`) and a string (`str`). Instead, it shows a **TypeError** and tells us the two types can't be compared together. -Між іншим, ви щойно дізналися про новий типу об'єкту в Python. Він називається логічним - __Boolean__ - і, можливо, це найпростіший тип. +## Boolean + +Incidentally, you just learned about a new type of object in Python. It's called **Boolean**. + +There are only two Boolean objects: -Існує лише два логічних об'єкти: - Істинне: True - Хибне: False -Але для того, щоб Python міг це зрозуміти, треба завжди писати 'True' (перша літера - велика, а решта - маленькі). __true, TRUE, tRUE не працюють - лише True є правильним.__ (Те ж саме стосується і 'False' також.) +But for Python to understand this, you need to always write it as 'True' (first letter uppercase, with the rest of the letters lowercased). **true, TRUE, and tRUE won't work – only True is correct.** (The same applies to 'False' as well.) + +Booleans can be variables, too! See here: -Логічні значення також можуть бути змінними! Погляньте: +{% filename %}command-line{% endfilename %} - >>> a = True - >>> a - True +```python +>>> a = True +>>> a +True +``` -Можна також зробити теж саме по-іншому: +You can also do it this way: - >>> a = 2 > 5 - >>> a - False +{% filename %}command-line{% endfilename %} -Практикуйте із логічними типами спробувавши запустити наступні команди: +```python +>>> a = 2 > 5 +>>> a +False +``` + +Practice and have fun with Booleans by trying to run the following commands: - `True and True` - `False and True` - `True or 1 == 1` - `1 != 2` -Вітання! Логічними типи - одна із найкрутіших властивостей програмування, і ви щойно освоїли, як їх застосовувати! +Congrats! Booleans are one of the coolest features in programming, and you just learned how to use them! # Збережіть! -Досі ми писали увесь наш Python код в інтерпретаторі, що обмежує нас написанням лише одного рядка за раз. Зазвичай програми зберігаються у файлах і виконуються __інтерпретатором__ або __компілятором__ нашої мови програмування. Досі ми запускали наші програми одним рядком в Python __інтерпретаторі__. Для наступних задач нам знадобиться більше, ніж один рядок коду, отже, нам потрібно: +> For readers at home: this part is covered in the [Python Basics: Saving files and "If" statement](https://www.youtube.com/watch?v=dOAg6QVAxyk) video. + +So far we've been writing all our python code in the interpreter, which limits us to entering one line of code at a time. Normal programs are saved in files and executed by our programming language **interpreter** or **compiler**. So far we've been running our programs one line at a time in the Python **interpreter**. We're going to need more than one line of code for the next few tasks, so we'll quickly need to: -- Закрити Python інтепретатор -- Відкрити наш вибраний текстовий редактор -- Зберегти певний код в python файлі +- Закрити інтерпретатор Python +- Відкрити редактор коду, який ми обрали +- Зберегти певний код у Python-файлі - Запустити його! -Щоб вийти з Python інтерпретатора, яким ми користувалися до цього, просто наберіть функцію ```exit()```: +To exit from the Python interpreter that we've been using, type the `exit()` function - >>> exit() - $ +{% filename %}command-line{% endfilename %} -Ви повернетеся назад до командного рядка. +```python +>>> exit() +$ +``` + +This will put you back into the command prompt. + +Earlier, we picked out a code editor from the [code editor](../code_editor/README.md) section. We'll need to open the editor now and write some code into a new file (or if you're using a Chromebook, create a new file in the cloud IDE and open the file, which will be in the included code editor): -Раніше ми вже обрали для себе редактор коду в розділі [редактор коду](../code_editor/README.md). А тепер ми маємо відкрити цей редактор і написати якийсь код в новому файлі: +{% filename %}editor{% endfilename %} ```python print('Hello, Django girls!') ``` -Очевидно, ви тепер є досить досвідченим Python програмістом, отже, можете написати у ваш код усе, що ви до цього часу вивчили. +Obviously, you're a pretty seasoned Python developer now, so feel free to write some code that you've learned today. -А тепер треба зберегти файл і дати йому описове ім'я. Назвімо файл **python_intro.py** і збережемо його на вашому робочому столі. Ви можете називати файл як завгодно, тільки важливо, щоб назва закінчувалась на __.py__. Закінчення __.py__ говорить нашій операційній системі, що це **виконуваний файл Python** і Python може його запускати. +Now we need to save the file and give it a descriptive name. Let's call the file **python_intro.py** and save it to your desktop. We can name the file anything we want, but the important part here is to make sure the file ends in **.py**. The **.py** extension tells our operating system that this is a **Python executable file** and Python can run it. -> **Примітка** Ви повинні помітити одну з найкрутіших фіч редакторів коду: кольори! У консолі Python все було одного кольору, тепер ви повинні побачити, що функція `print` має інший колір, ніж рядок, який вона друкує. Це називається "підсвіткою синтаксису", і це справді корисна функція для програміста. Різний колір слів дає вам підказку щодо правильності набору тексту чи орфографічної помилки (згодом зверніть увагу на колір слова `def` в тілі функції). Це одна з вагомих причин, чому ми використовуємо редактор коду :) +> **Note** You should notice one of the coolest thing about code editors: colors! In the Python console, everything was the same color; now you should see that the `print` function is a different color from the string. This is called "syntax highlighting", and it's a really useful feature when coding. The color of things will give you hints, such as unclosed strings or a typo in a keyword name (like the `def` in a function, which we'll see below). This is one of the reasons we use a code editor. :) +With the file saved, it's time to run it! Using the skills you've learned in the command line section, use the terminal to **change directories** to the desktop. -По тому, як файл успішно збережено, час запустити його! Використовуючи навики отримані під час освоєння розділу, що стосувався командного рядка, скористайтеся терміналом, щоб **змінити директорію** на робочий стіл. + -Для Mac, команда буде виглядати так: +On a Mac, the command will look something like this: + +{% filename %}command-line{% endfilename %} $ cd ~/Desktop + + + + + -Для Linux, вона буде на зразок (слово "Desktop" може бути перекладене вашою мовою): +On Linux, it will be like this: + +{% filename %}command-line{% endfilename %} $ cd ~/Desktop + + +(Remember that the word "Desktop" might be translated to your local language.) + + + + -І для Windows, це буде так: +On Windows Command Prompt, it will be like this: + +{% filename %}командний рядок{% endfilename %} > cd %HomePath%\Desktop + + + + + -Якщо ви застрягли, просто попросіть допомоги. +And on Windows Powershell, it will be like this: -Використовуйте Python, щоб виконати код у файлі, таким чином: +{% filename %}command-line{% endfilename %} + + > cd $Home\Desktop + + + + +If you get stuck, ask for help. That's exactly what the coaches are here for! + +Now use Python to execute the code in the file like this: + +{% filename %}командний рядок{% endfilename %} $ python3 python_intro.py Hello, Django girls! + -Гаразд! Ви щойно запустили вашу першу Python програму, яка була збережена у файлі. Чудові відчуття? +Note: on Windows 'python3' is not recognized as a command. Instead, use 'python' to execute the file: -Тепер ви можете переходити до важливого інструменту у програмуванні: +{% filename %}command-line{% endfilename %} -## If...elif...else +```python +> python python_intro.py +``` + +Alright! You just ran your first Python program that was saved to a file. Feel awesome? + +You can now move on to an essential tool in programming: + +## If … elif … else -Багато речей в програмі мають бути виконані лише тоді, коли виконуються задані умови. Саме тому Python має інструмент, що називається __умовою if - якщо__. +Lots of things in code should be executed only when given conditions are met. That's why Python has something called **if statements**. -Замініть код вашого файлу **python_intro.py** на наступне: +Replace the code in your **python_intro.py** file with this: + +{% filename %}python_intro.py{% endfilename %} ```python if 3 > 2: ``` -Якщо ми збережемо зміни і запустимо цей файл, то побачимо наступну помилку: +If we were to save and run this, we'd see an error like this: + +{% filename %}{{ warning_icon }} command-line{% endfilename %} $ python3 python_intro.py File "python_intro.py", line 2 ^ SyntaxError: unexpected EOF while parsing + + +Python expects us to give further instructions to it which are executed if the condition `3 > 2` turns out to be true (or `True` for that matter). Let’s try to make Python print “It works!”. Change your code in your **python_intro.py** file to this: -Python очікує від нас подальших інструкцій, які повинні бути виконані, якщо умова `3 > 2` виявляється істинною (тобто `True`). Спробуємо змусити Python надрукувати “It works!”. Змініть код у файлі **python_intro.py** на наступне: +{% filename %}python_intro.py{% endfilename %} ```python if 3 > 2: print('It works!') ``` -Зауважили, яким чином ми зробили відступ в 4 пробіли для наступного рядка коду? Це необхідно робити для того, щоб Python знав, який шматок коду запускати, якщо результати умови істинні. Можна зробити відступ і в один пробіл, але майже усі Python програмісти роблять відступ у 4 пробіли, щоб було акуратніше. Один `tab` також рахується як 4 пробіли. +Notice how we've indented the next line of code by 4 spaces? We need to do this so Python knows what code to run if the result is true. You can do one space, but nearly all Python programmers do 4 to make things look neat. A single Tab will also count as 4 spaces as long as your text editor is set to do so. When you made your choice, don't change it! If you already indented with 4 spaces, make any future indentation with 4 spaces, too - otherwise you may run into problems. -Збережіть і запустіть знову: +Save it and give it another run: - $ python3 python_intro.py - It works! +{% filename %}command-line{% endfilename %} + +```python +$ python3 python_intro.py +It works! +``` + +Note: Remember that on Windows, 'python3' is not recognized as a command. From now on, replace 'python3' with 'python' to execute the file. + +### А що, коли умова не істинна (тобто False)? -### Що ж, якщо ні? +In previous examples, code was executed only when the conditions were True. But Python also has `elif` and `else` statements: -У попередніх прикладах код виконувався лише, коли умови були істинними - True. Однак, Python також має умови `elif` та `else`: +{% filename %}python_intro.py{% endfilename %} ```python if 5 > 2: @@ -505,12 +739,17 @@ else: print('5 is not greater than 2') ``` -Коли запустимо це, буде виведено: +When this is run it will print out: + +{% filename %}command-line{% endfilename %} $ python3 python_intro.py 5 is indeed greater than 2 + + +If 2 were a greater number than 5, then the second command would be executed. Let's see how `elif` works: -Якщо 2 було числом більшим за 5, то далі буде виконуватися друга команда. Просто, правда ж? Подивимося як працює `elif`: +{% filename %}python_intro.py{% endfilename %} ```python name = 'Sonja' @@ -522,14 +761,19 @@ else: print('Hey anonymous!') ``` -і в результаті: +and executed: + +{% filename %}command-line{% endfilename %} $ python3 python_intro.py Hey Sonja! + + +See what happened there? `elif` lets you add extra conditions that run if the previous conditions fail. -Бачите, що тут відбуваеться? `Elif` вказує додаткові умови для перевірки, якщо результат попередніх умов є невдалим. +You can add as many `elif` statements as you like after your initial `if` statement. For example: -Ви можете додати стільки виразів `elif`, скільки вам до вподоби одразу після виразу `if`. Наприклад: +{% filename %}python_intro.py{% endfilename %} ```python volume = 57 @@ -547,27 +791,52 @@ else: print("My ears are hurting! :(") ``` -Python послідовно виконує всі перевірки та друкує: +Python runs through each test in sequence and prints: + +{% filename %}command-line{% endfilename %} $ python3 python_intro.py Perfect, I can hear all the details + + +## Comments + +Comments are lines beginning with `#`. You can write whatever you want after the `#` and Python will ignore it. Comments can make your code easier for other people to understand. + +Let's see how that looks: + +{% filename %}python_intro.py{% endfilename %} + +```python +# Change the volume if it's too loud or too quiet +if volume < 20 or volume > 80: + volume = 50 + print("That's better!") +``` + +You don't need to write a comment for every line of code, but they are useful for explaining why your code is doing something, or providing a summary when it's doing something complex. ### Підсумок -В останніх трьох вправах ви освоїли такі поняття, як: +In the last few exercises you learned about: -- __порівняння__ - в Python можна порівнювати елементи використовуючи `>`, `>=`, `==`, `<=`, `<` та оператори `and`, `or` -- __Логічний тип - Boolean__ - тип об'єкту, що може дорівнювати лише одному з двох значень: `True`- Істинне або `False` - Хибне -- __Збереження файлів__ - зберігання коду в файлах дозволяє виконувати більші програми. -- __if...elif...else__ - умови, що дозволяють виконувати код лише коли виконуються певні умови. +- **Порівняння** – в Python можна порівнювати елементи використовуючи `>`, `>=`, `==`, `<=`, `<` та оператори `and`, `or`; +- **Логічний тип (Boolean)** – тип об'єкту, що може приймати лише одне з двох значень: `True` (істинне) або `False` (хибне); +- **Збереження файлів** – зберігання коду в файлах дозволяє виконувати більші за розміром програми; +- **if...elif...else** – інструкції, що дозволяють виконувати код, лише коли задовольняються певні умови. +- **Коментарі** – рядки коду, які Python не запускає, але які дозволяють вам документувати код. -Час для останньої частини цього параграфу! +Time for the last part of this chapter! -## Ваші власні функції! +## Your own functions! -Пам'ятаєте функції на зразок `len()`, що можна виконувати в Python? Що ж, гарні новини - зараз ви дізнаєтесь, як писати свої власні функції! +> For readers at home: this part is covered in the [Python Basics: Functions](https://www.youtube.com/watch?v=5owr-6suOl0) video. -Функція - це набір інструкцій, які Python повинен виконати. Кожна функція в Python починається із ключового слова `def`, отримує ім'я і може містити певні параметри. Почнемо з простого. Перепишемо код в **python_intro.py** наступним чином: +Remember functions like `len()` that you can execute in Python? Well, good news – you will learn how to write your own functions now! + +A function is a sequence of instructions that Python should execute. Each function in Python starts with the keyword `def`, is given a name, and can have some parameters. Let's give it a go. Replace the code in **python_intro.py** with the following: + +{% filename %}python_intro.py{% endfilename %} ```python def hi(): @@ -577,23 +846,36 @@ def hi(): hi() ``` -Окей, наша перша функція готова! +Okay, our first function is ready! -Ви можете запитати, для чого ми написали ім'я функції наприкінці файлу. Це тому, що Python зчитує файл і виконує його згори донизу. Отже, для того, щоб скористатися нашою функцією, ми повинні написати її знову унизу. +You may wonder why we've written the name of the function at the bottom of the file. When we write `def hi():` and the indented lines following, this is us writing instructions for what the `hi()` function should do. Python will read and remember these instructions, but won't run the function yet. To tell Python we want to run the function, we have to call the function with `hi()`. Python reads the file and executes it from top to bottom, so we have to define the function in the file before we call it. -А тепер запустимо і подивимось, що станеться: +Let's run this now and see what happens: + +{% filename %}command-line{% endfilename %} $ python3 python_intro.py Hi there! How are you? + + +Note: if it didn't work, don't panic! The output will help you to figure why: -Це було просто! Побудуємо нашу першу функцію з параметрами. Скористаємося попереднім прикладом - функцією, що говорить 'hi' особі, що її запускає - з іменем: +- Якщо ви отримаєте `NameError` (помилку імені), це, мабуть, означає, що ви ввели неправильне ім'я: тоді треба перевірити, що ви використовуєте одне й те ж ім'я під час створення функції через `def hi():` і коли викликаєте її за допомогою `hi()`. +- Якщо у вас `IndentationError` (помилка відступу), перевірте, чи мають обидва рядки `print` однакову кількість пробілів на початку рядка: Python хоче, щоб весь код всередині функції був чітко вирівняний. +- Якщо ж на екран взагалі нічого не вивелося, перевірте, що *немає* пробілів перед останнім `hi()`, – якщо вони є, цей рядок також стане частиною функції і ніколи не запуститься. + +Let's build our first function with parameters. We will change the previous example – a function that says 'hi' to the person running it – with a name: + +{% filename %}python_intro.py{% endfilename %} ```python def hi(name): ``` -Як бачимо, зараз ми задали для нашої функції параметр, який назвали `name`: +As you can see, we now gave our function a parameter that we called `name`: + +{% filename %}python_intro.py{% endfilename %} ```python def hi(name): @@ -607,45 +889,61 @@ def hi(name): hi() ``` -Пам'ятайте: функція `print` відділена відступами від команди `if` на чотири пробіли. Це тому, що функція запускається, коли виконується умова. Давайте подивимося, як це відбувається зараз: +Remember: The `print` function is indented four spaces within the `if` statement. This is because the function runs when the condition is met. Let's see how it works now: + +{% filename %}{{ warning_icon }} command-line{% endfilename %} $ python3 python_intro.py Traceback (most recent call last): File "python_intro.py", line 10, in hi() TypeError: hi() missing 1 required positional argument: 'name' + + +Oops, an error. Luckily, Python gives us a pretty useful error message. It tells us that the function `hi()` (the one we defined) has one required argument (called `name`) and that we forgot to pass it when calling the function. Let's fix it at the bottom of the file: -Ой, помилка. На щастя, Python надає нам дуже корисне повідомлення про помилку. -Воно повідомляє нас про те, що функція `hi()` (та, яку ми визначили) має один необхідний аргумент (`name`) і що ми забули передати його, коли здійснювали виклик функції. -Виправимо це наприкінці файлу: +{% filename %}python_intro.py{% endfilename %} ```python hi("Ola") ``` -І запустимо знову: +And run it again: + +{% filename %}command-line{% endfilename %} $ python3 python_intro.py Hi Ola! + -А якщо ми змінимо ім'я? +And if we change the name? + +{% filename %}python_intro.py{% endfilename %} ```python hi("Sonja") ``` -Запустимо: +And run it: + +{% filename %}command-line{% endfilename %} $ python3 python_intro.py Hi Sonja! + + +Now, what do you think will happen if you write another name in there? (Not Ola or Sonja.) Give it a try and see if you're right. It should print out this: -А тепер що ви думаєте про те, що станеться, якщо ми вкажемо тут інше ім'я? (Не Ola і не Sonja) Спробуємо і подивимося, чи ви маєте рацію. Маємо отримати на виході: +{% filename %}command-line{% endfilename %} Hi anonymous! + -Чудово, чи не так? Таким чином вам не потрібно повторюватись кожного разу, коли ви захочете змінити ім'я особи, з якою має вітатися наша функція. І саме тому нам потрібні функції - ви ж бо ніколи не хочете повторювати свій код! +This is awesome, right? This way you don't have to repeat yourself every time you want to change the name of the person the function is supposed to greet. And that's exactly why we need functions – you never want to repeat your code! -Виконаємо дещо складніші маніпуляції - існує безліч імен, набагато більше, ніж лише два, і написати умови для кожного з них буде досить складно, правда ж? +Let's do something smarter – there are more names than two, and writing a condition for each would be hard, right? Replace the content of your file with the following: + +{% filename %}python_intro.py{% endfilename %} ```python def hi(name): @@ -654,34 +952,45 @@ def hi(name): hi("Rachel") ``` -А тепер виконаємо програму: +Let's call the code now: + +{% filename %}command-line{% endfilename %} $ python3 python_intro.py Hi Rachel! + + +Congratulations! You just learned how to write functions! :) -Вітаємо! Ви щойно розібралися з тим, як писати функції :) +## Loops -## Цикли +> For readers at home: this part is covered in the [Python Basics: For Loop](https://www.youtube.com/watch?v=aEA6Rc86HF0) video. -Це вже остання частина. Усе було швидко, чи не так? :) +This is the last part already. That was quick, right? :) -Програмісти не люблять повторюватись. Програмування - це процес автоматизації всього, тому ми не хочемо вітати кожну людину по імені вручну, правильно? Тут пригодяться цикли. +Programmers don't like to repeat themselves. Programming is all about automating things, so we don't want to greet every person by their name manually, right? That's where loops come in handy. -Ще пам'ятаєте про списки? Давайте створимо список дівчат: +Still remember lists? Let's do a list of girls: + +{% filename %}python_intro.py{% endfilename %} ```python girls = ['Rachel', 'Monica', 'Phoebe', 'Ola', 'You'] ``` -Ми б хотіли привітатися із кожною з них персонально. Щоб це зробити, у нас є функція `hi`, отже, використаємо її в циклі: +We want to greet all of them by their name. We have the `hi` function to do that, so let's use it in a loop: + +{% filename %}python_intro.py{% endfilename %} ```python for name in girls: ``` -Вираз ```for``` поводиться подібно до виразу ```if```, а код, наведений нижче повинен мати відступи в чотири пробіли. +The `for` statement behaves similarly to the `if` statement; code below both of these need to be indented four spaces. + +Here is the full code that will be in the file: -Тут наведено повну версію коду у файлі: +{% filename %}python_intro.py{% endfilename %} ```python def hi(name): @@ -693,7 +1002,9 @@ for name in girls: print('Next girl') ``` -А коли ми запустимо усе це: +And when we run it: + +{% filename %}command-line{% endfilename %} $ python3 python_intro.py Hi Rachel! @@ -706,30 +1017,40 @@ for name in girls: Next girl Hi You! Next girl + + +As you can see, everything you put inside a `for` statement with an indent will be repeated for every element of the list `girls`. + +You can also use `for` on numbers using the `range` function: -Як бачимо, все, що міститься всередині виразу `for` із відступом буде повторюватися для кожного елементу зі списку `girls`. +{% filename %}python_intro.py{% endfilename %} -Також можна використовувати `for` для чисел, використовуючи функцію `range`: +```python +for i in range(1, 6): + print(i) +``` - for i in range(1, 6): - print(i) +Which would print: -Що виведе на екран: +{% filename %}command-line{% endfilename %} 1 2 3 4 5 + + +`range` is a function that creates a list of numbers following one after the other (these numbers are provided by you as parameters). -`range` - це функція, що створює список чисел, що йдуть одне за одним ці числа задаються вами як параметри). +Note that the second of these two numbers is not included in the list that is output by Python (meaning `range(1, 6)` counts from 1 to 5, but does not include the number 6). That is because "range" is half-open, and by that we mean it includes the first value, but not the last. -Зауважте, що друге з цих двох чисел, не входить до списку, що виводиться на екран Python (тобто `range(1, 6)` рахує від 1 до 5, але не включає число 6). Це тому, що "діапазон" є напіввідкритим, і під цим ми розуміємо, що він включає перше значення, але не останнє. +## Summary -## Підсумок +That's it. **You totally rock!** This was a tricky chapter, so you should feel proud of yourself. We're definitely proud of you for making it this far! -Ось і все. __Ви молодці!__ Це був складнуватий розділ, тому ви можете пишатися собою. Ми ж безумовно пишаємося вами, адже ви вже багато чого досягли! +For official and full python tutorial visit https://docs.python.org/3/tutorial/. This will give you a more thorough and complete study of the language. Cheers! :) -Ви можете зробити коротку перерву - можливо потрібний відпочинок для ваших очей, розминка, невелика прогулянка, перш ніж перейдете до наступного розділу. :) +You might want to briefly do something else – stretch, walk around for a bit, rest your eyes – before going on to the next chapter. :) -![Cupcake](images/cupcake.png) +![Cupcake](images/cupcake.png) \ No newline at end of file diff --git a/uk/python_introduction/prompt.md b/uk/python_introduction/prompt.md new file mode 100644 index 00000000000..27f422934c0 --- /dev/null +++ b/uk/python_introduction/prompt.md @@ -0,0 +1,17 @@ +## Python prompt + +> For readers at home: this part is covered in the [Python Basics: Integers, Strings, Lists, Variables and Errors](https://www.youtube.com/watch?v=MO63L4s-20U) video. + +To start playing with Python, we need to open up a *command line* on your computer. You should already know how to do that – you learned it in the [Intro to Command Line](../intro_to_command_line/README.md) chapter. + +Once you're ready, follow the instructions below. + +We want to open up a Python console, so type in `python` on Windows or `python3` on Mac OS/Linux and hit `enter`. + +{% filename %}command-line{% endfilename %} +``` +$ python3 +Python {{ book.py_release }} (...) +Type "help", "copyright", "credits" or "license" for more information. +>>> +``` diff --git a/uk/template_extending/README.md b/uk/template_extending/README.md old mode 100755 new mode 100644 index 8d35894913f..9c1d80df6db --- a/uk/template_extending/README.md +++ b/uk/template_extending/README.md @@ -1,12 +1,12 @@ # Розширення шаблону -Інша хороша річ, яку має Django в своєму арсеналі - це __розширення шаблону__. Що це означає? Це значить, що ви можете використовувати одні й ті ж частини свого HTML коду для різних сторінок веб-сайту. +Інша хороша річ, яку має Django у своєму арсеналі це **шаблонне розширення**. Що це означає? А це означає, що ви можете використовувати одні й ті ж частини свого HTML коду для різних сторінок вебсайту. -Шаблони допомогають у випадку, коли ви хочете використати однакову інформацію/схему. Вам не потрібно повторюватись в кожному файлі. І якщо ви захочете щось змінити, то не доведеться це робити в кожному шаблоні, а лише один раз! +Шаблони допомагають коли ви хочете використати одну і ту ж інформацію чи макет у більш ніж одному місці. Ви можете не повторюватись у кожному файлі. І якщо ви хочете щось змінити, не потрібно робити це в кожному шаблоні, лише в одному! ## Створення базового шаблону -Базовий шаблон - це основний шаблон, який ви будете розширювати для кожної сторінки вашого веб-сайту. +Базовий шаблон - це основний шаблон, який ви будете розширювати для кожної сторінки вашого вебсайту. Створимо файл `base.html` в `blog/templates/blog/`: @@ -15,120 +15,137 @@ └───blog base.html post_list.html + -Відкрийте його і скопіюйте усе з `post_list.html` до файлу `base.html`, як тут: +Тепер відкрийте його і скопіюйте усе з `post_list.html` до файлу `base.html`, як тут: + +{% filename %}blog/templates/blog/base.html{% endfilename %} ```html {% load static %} + Django Girls blog - - + - + -
+
-
+
{% for post in posts %} -
-
+
+
-

{{ post.title }}

+ +

{{ post.title }}

{{ post.text|linebreaksbr }}

-
+ {% endfor %}
-
+
``` -Далі для `base.html`, замініть ціле тіло `` (все між `` і ``) цим: +Далі в `base.html`, замініть весь вміст `` (все між `` і ``) на це: + +{% filename %}blog/templates/blog/base.html{% endfilename %} ```html - -
+ +
-
+
{% block content %} {% endblock %}
-
+
``` -{% raw %}Зауважте, це замінило все, починаючи від `{% for post in posts %}` до `{% endfor %}`, цим: {% endraw %} +{% raw %}Ви могли помітити, що замінилось все від `{% for post in posts %}` до `{% endfor %}` на це: {% endraw %} + +{% filename %}blog/templates/blog/base.html{% endfilename %} ```html {% block content %} {% endblock %} ``` -Що це означає? Ви щойно створили блок `block`! Використали шаблонний тег `{% block %}` для того, щоб створити місце, в яке буде вставлено HTML. Цей HTML міститиметься в інших шаблонах, які розширюють цей шаблон (`base.html`). Скоро ми покажемо вам, як це зробити. -А тепер збережіть зміни і відкрийте знову свій `blog/templates/blog/post_list.html`. -{% raw %}Видаліть усе, що вище `{% for post in posts %}` і нижче `{% endfor %}`. Коли ви закінчите, файл виглядатиме так:{% endraw %} +Але навіщо? Ви щойно створили `block`! Ви використали тег шаблону `{% block %}`, щоб зробити область, в яку буде введений HTML. Цей HTML буде взятий з іншого шаблону, який розширить шаблон `base.html`. Скоро ми покажемо вам як це зробити. + +Тепер збережіть `base.html` і знову відкрийте ваш `blog/templates/blog/post_list.html` в редакторі коду. {% raw %}Вам треба видалити все перед `{% for post in posts %}` та після `{% endfor %}`. Коли ви закінчите, файл буде виглядати так:{% endraw %} + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html {% for post in posts %} -
-
+
+
-

{{ post.title }}

+ +

{{ post.title }}

{{ post.text|linebreaksbr }}

-
+ {% endfor %} ``` -Ми хочемо використати це як частина нашого шаблону для всіх блоків контенту. -Час додати теги блоків до цього файлу! +Ми хочемо використати це як частину нашого шаблону для всіх блоків контенту. Час додати теги блоків до цього файлу! -{% raw %}Ви хочете, щоб ваший тег блоку підходив до тегу у файлі `base.html`. Ви такоже хочете, щоб він включав в себе весь код, що належить вашим блокам з контентом. Щоб зробити це, розмістіть все між `{% block content %}` і `{% endblock %}`. Як тут: {% endraw %} +{% raw %}Ви хочете, щоб ваш тег блоку відповідав тегу у файлі `base.html`. Ви також хочете включити весь код, який треба до ваших блоків контенту. Для цього вставте все між `{% block content %}` та `{% endblock %}`. Наступним чином:{% endraw %} -```html +{% filename %}blog/templates/blog/post_list.html{% endfilename %} +```html {% block content %} {% for post in posts %} -
-
+
+
-

{{ post.title }}

+ +

{{ post.title }}

{{ post.text|linebreaksbr }}

-
+ {% endfor %} {% endblock %} ``` -Залишився один момент. Нам потрібно поєднати ці два шаблони разом. Це і є розширенням шаблонів. Ми зробимо це додаванням на початок файлу тегу розширення. Як тут: + +Залишилося лише одне. Нам необхідно з'єднати ці два шаблони разом. Це і є розширення шаблону! Ми зробимо це, додавши додатковий тег до початку файлу. Як тут: + +{% filename %}blog/templates/blog/post_list.html{% endfilename %} + ```html {% extends 'blog/base.html' %} {% block content %} {% for post in posts %} -
-
+
+
-

{{ post.title }}

+ +

{{ post.title }}

{{ post.text|linebreaksbr }}

-
+ {% endfor %} {% endblock %} ``` -Ось і все! Перевірте, чи ваш сайт все ще коректно працює :) +Ось і все! Збережіть файл, та перевірте чи ваш сайт все ще працює належним чином. :) -> Якщо з'явилася помилка `TemplateDoesNotExists`, то це говорить про те, що файлу `blog/base.html` не існує і ви маєте в консолі запущений `runserver`, спробуйте зупинити його (натиснувши Ctrl+C - кнопки Control і C buttons разом) і перезавантажити командою `python manage.py runserver`. +> Якщо з'явилась помилка `TemplateDoesNotExist`, то це означає що відсутній файл `blog/base.html` і у вас запущений `runserver` в консолі. Спробуйте зупинити його (натиснувши Ctrl+C – клавіші Control та C разом) та перезавантажте його, запустивши команду `python manage.py runserver`. \ No newline at end of file diff --git a/uk/whats_next/README.md b/uk/whats_next/README.md old mode 100755 new mode 100644 index 349f6dc0008..5fda63017e1 --- a/uk/whats_next/README.md +++ b/uk/whats_next/README.md @@ -1,26 +1,43 @@ # Що далі? -Привітайте себе! __Ви абсолютно неймовірні.__ Ми пишаємося вами! <3 +Привітайте себе! **Ви абсолютно неймовірні**. Ми пишаємося вами! <3 ### Що тепер робити? -Перепочиньте і розслабтеся. Ви щойно створили щось дійсно велике. +Зробіть паузу та розслабтеся! Ви щойно зробили щось дійсно велике. -Після цього переконайтеся, що ви: +Після цього слідкуйте за Django Girls на [Facebook](http://facebook.com/djangogirls) або [Twitter](https://twitter.com/djangogirls), щоб залишатися в курсі. -- Підписалися на Django Girls у [Facebook](http://facebook.com/djangogirls) або в [Twitter](https://twitter.com/djangogirls), щоб бути в курсі усіх подій +### Чи можете порекомендувати інші джерела? -### Чи можете ви порекомендувати інші джерела? +Так! В Інтернеті є *багато* ресурсів для вивчення різного роду навичок програмування – може бути досить складно визначити, куди йти далі, але ми підготуємо вас. Незалежно від того, які ваші інтереси були до того, як ви приєднались до Django Girls, і будь-які інтереси, які з'явилися після проходження цього туторіалу, ось деякі безкоштовні ресурси (або ресурси з великою кількістю безкоштовних компонентів) , які ви можете використовувати щоб дістатися туди, де ви хочете бути. -Так! Спершу, спробуйте нашу іншу книгу [Django Girls Tutorial: Extensions](https://tutorial-extensions.djangogirls.org). +#### Django -Пізніше, ви можете спробувати джерела, перелічені нижче. Дуже рекомендуємо! -- [Django's official tutorial](https://docs.djangoproject.com/en/1.8/intro/tutorial01/) -- [New Coder tutorials](http://newcoder.io/tutorials/) -- [Code Academy Python course](https://www.codecademy.com/en/tracks/python) -- [Code Academy HTML & CSS course](https://www.codecademy.com/tracks/web) -- [Django Carrots tutorial](https://github.com/ggcarrots/django-carrots) -- [Learn Python The Hard Way book](http://learnpythonthehardway.org/book/) -- [Getting Started With Django video lessons](http://www.gettingstartedwithdjango.com/) -- [Two Scoops of Django: Best Practices for Django 1.8 book](https://twoscoopspress.com/products/two-scoops-of-django-1-8) -- [Hello Web App: Learn How to Build a Web App](https://hellowebapp.com/) +- Наша інша книга [Django Girls Tutorial: Extensions](https://tutorial-extensions.djangogirls.org/) +- [Офіційний туторіал Django](https://docs.djangoproject.com/en/3.2/intro/tutorial01/) +- [Відеоуроки "Getting Started With Django"](http://www.gettingstartedwithdjango.com/) +- [Django for Everybody Specialization](https://www.coursera.org/specializations/django) - декілька відеолекцій, які можна безкоштовно переглядати і ви можете навіть отримати сертифікат Coursera, пройшовши ці курси + +#### HTML/CSS/JavaScript + +- [Курс веб-розробки Codecademy](https://www.codecademy.com/learn/paths/web-development) +- [freeCodeCamp](https://www.freecodecamp.org/) + +#### Python + +- [Курс Python від Codecademy](https://www.codecademy.com/learn/learn-python) +- [Курс Python від Google](https://developers.google.com/edu/python/) +- [Learn Python The Hard Way book](http://learnpythonthehardway.org/book/) – початкові вправи є безкоштовними +- [New Coder tutorials](http://newcoder.io/tutorials/) – це різноманітні практичні приклади того, як ви можете використовувати Python +- [edX](https://www.edx.org/course?search_query=python) – ви можете перевірити більшість курсів безкоштовно, але якщо ви хочете отримати сертифікат або кредити для отримання кваліфікації вищої освіти, це буде коштувати грошей +- [Спеціалізація Coursera Python](https://www.coursera.org/specializations/python) – деякі відеолекції можна безкоштовно перевіряти, і ви можете отримати сертифікат Coursera, пройшовши ці курси +- [Python for Everybody](https://www.py4e.com/) - безкоштовний і відкритий варіант курсу Python for Everybody specialization від Coursera + +#### Робота з даними + +- [Курс науки про дані від Codecademy](https://www.codecademy.com/learn/paths/data-science) +- [edX](https://www.edx.org/course/?search_query=python&subject=Data%20Analysis%20%26%20Statistics) - ви можете переглядати більшість курсів безкоштовно, але якщо ви захочете отримати сертифікат або кредити до вищої освіти, то це буде коштувати грошей +- [Dataquest](https://www.dataquest.io/) - перші 30 "місій" є безкоштовними + +Ми не можемо дочекатися, щоб побачити, що ви створюєте далі! \ No newline at end of file